Skip to content

Commit 3ec3421

Browse files
authored
Merge pull request #81604 from hamishknight/pretty-crash
Adopt `ABORT` throughout the compiler
2 parents 998a676 + edca7c8 commit 3ec3421

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+894
-761
lines changed

include/swift/Basic/Assertions.h

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,22 @@
1717
#ifndef SWIFT_BASIC_ASSERTIONS_H
1818
#define SWIFT_BASIC_ASSERTIONS_H
1919

20+
#include "swift/Basic/LLVM.h"
21+
2022
// Only for use in this header
2123
#if __has_builtin(__builtin_expect)
2224
#define ASSERT_UNLIKELY(expression) (__builtin_expect(!!(expression), 0))
2325
#else
2426
#define ASSERT_UNLIKELY(expression) ((expression))
2527
#endif
2628

29+
// Visual Studio doesn't have __FILE_NAME__
30+
#ifdef __FILE_NAME__
31+
#define _FILENAME_FOR_ASSERT __FILE_NAME__
32+
#else
33+
#define _FILENAME_FOR_ASSERT __FILE__
34+
#endif
35+
2736
// ================================ Mandatory Asserts ================================
2837

2938
// `ASSERT(expr)`:
@@ -41,27 +50,13 @@
4150
// that are more expensive than you think. You can switch those to
4251
// `CONDITIONAL_ASSERT` or `DEBUG_ASSERT` as needed.
4352

44-
// Visual Studio doesn't have __FILE_NAME__
45-
#ifdef __FILE_NAME__
46-
47-
#define ASSERT(expr) \
48-
do { \
49-
if (ASSERT_UNLIKELY(!(expr))) { \
50-
ASSERT_failure(#expr, __FILE_NAME__, __LINE__, __func__); \
51-
} \
53+
#define ASSERT(expr) \
54+
do { \
55+
if (ASSERT_UNLIKELY(!(expr))) { \
56+
ASSERT_failure(#expr, _FILENAME_FOR_ASSERT, __LINE__, __func__); \
57+
} \
5258
} while (0)
5359

54-
#else
55-
56-
#define ASSERT(expr) \
57-
do { \
58-
if (ASSERT_UNLIKELY(!(expr))) { \
59-
ASSERT_failure(#expr, __FILE__, __LINE__, __func__); \
60-
} \
61-
} while (0)
62-
63-
#endif
64-
6560
// Function that reports the actual failure when it occurs.
6661
void ASSERT_failure(const char *expr, const char *file, int line, const char *func);
6762

@@ -190,11 +185,33 @@ extern int CONDITIONAL_ASSERT_Global_enable_flag;
190185
#define SWIFT_ASSERT_ONLY_DECL DEBUG_ASSERT_DECL
191186
#define SWIFT_ASSERT_ONLY DEBUG_ASSERT_EXPR
192187

193-
// ================================ Utility and Helper Functions ================================
188+
// ================================ Abort ======================================
194189

195-
// Utility function to print out help information for
196-
// various command-line options that affect the assertion
197-
// behavior.
198-
void ASSERT_help();
190+
/// Implementation for \c ABORT, not to be used directly.
191+
[[noreturn]]
192+
void _ABORT(const char *file, int line, const char *func,
193+
llvm::function_ref<void(llvm::raw_ostream &)> message);
194+
195+
/// Implementation for \c ABORT, not to be used directly.
196+
[[noreturn]]
197+
void _ABORT(const char *file, int line, const char *func,
198+
llvm::StringRef message);
199+
200+
// Aborts the program, printing a given message to a PrettyStackTrace frame
201+
// before exiting. This should be preferred over manually logging to stderr and
202+
// `abort()`'ing since that won't be picked up by the crash reporter.
203+
//
204+
// There are two different forms of ABORT:
205+
//
206+
// ```
207+
// ABORT("abort with string");
208+
//
209+
// ABORT([&](auto &out) {
210+
// out << "abort with arbitrary stream";
211+
// node.dump(out);
212+
// });
213+
// ```
214+
//
215+
#define ABORT(arg) _ABORT(_FILENAME_FOR_ASSERT, __LINE__, __func__, (arg))
199216

200217
#endif // SWIFT_BASIC_ASSERTIONS_H

include/swift/Basic/PrettyStackTrace.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,6 @@ class PrettyStackTraceSwiftVersion : public llvm::PrettyStackTraceEntry {
5050
void print(llvm::raw_ostream &OS) const override;
5151
};
5252

53-
/// Aborts the program, printing a given message to a PrettyStackTrace frame
54-
/// before exiting.
55-
[[noreturn]]
56-
void abortWithPrettyStackTraceMessage(
57-
llvm::function_ref<void(llvm::raw_ostream &)> message);
58-
59-
/// Aborts the program, printing a given message to a PrettyStackTrace frame
60-
/// before exiting.
61-
[[noreturn]]
62-
void abortWithPrettyStackTraceMessage(llvm::StringRef message);
63-
6453
} // end namespace swift
6554

6655
#endif // SWIFT_BASIC_PRETTYSTACKTRACE_H

include/swift/SIL/SILCloner.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -557,11 +557,12 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
557557
}
558558

559559
if (substConf.isInvalid()) {
560-
llvm::errs() << "Invalid substituted conformance in SIL cloner:\n";
561-
Functor.dump(llvm::errs());
562-
llvm::errs() << "\noriginal conformance:\n";
563-
conformance.dump(llvm::errs());
564-
abort();
560+
ABORT([&](auto &out) {
561+
out << "Invalid substituted conformance in SIL cloner:\n";
562+
Functor.dump(out);
563+
out << "\noriginal conformance:\n";
564+
conformance.dump(out);
565+
});
565566
}
566567

567568
if (asImpl().shouldSubstOpaqueArchetypes()) {

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5819,9 +5819,10 @@ ProtocolConformanceRef ProtocolConformanceRef::forAbstract(
58195819
break;
58205820

58215821
default:
5822-
llvm::errs() << "Abstract conformance with bad subject type:\n";
5823-
conformingType->dump(llvm::errs());
5824-
abort();
5822+
ABORT([&](auto &out) {
5823+
out << "Abstract conformance with bad subject type:\n";
5824+
conformingType->dump(out);
5825+
});
58255826
}
58265827

58275828
// Figure out which arena this should go in.

lib/AST/ASTMangler.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,8 +1446,7 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
14461446
case TypeKind::BuiltinUnsafeValueBuffer:
14471447
return appendOperator("BB");
14481448
case TypeKind::BuiltinUnboundGeneric:
1449-
llvm::errs() << "Don't know how to mangle a BuiltinUnboundGenericType\n";
1450-
abort();
1449+
ABORT("Don't know how to mangle a BuiltinUnboundGenericType");
14511450
case TypeKind::Locatable: {
14521451
auto loc = cast<LocatableType>(tybase);
14531452
return appendType(loc->getSinglyDesugaredType(), sig, forDecl);
@@ -1756,9 +1755,10 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
17561755
case TypeKind::PackArchetype:
17571756
case TypeKind::ElementArchetype:
17581757
case TypeKind::ExistentialArchetype:
1759-
llvm::errs() << "Cannot mangle free-standing archetype: ";
1760-
tybase->dump(llvm::errs());
1761-
abort();
1758+
ABORT([&](auto &out) {
1759+
out << "Cannot mangle free-standing archetype: ";
1760+
tybase->dump(out);
1761+
});
17621762

17631763
case TypeKind::OpaqueTypeArchetype: {
17641764
auto opaqueType = cast<OpaqueTypeArchetypeType>(tybase);
@@ -4468,8 +4468,7 @@ static unsigned conformanceRequirementIndex(
44684468
++result;
44694469
}
44704470

4471-
llvm::errs() <<"Conformance access path step is missing from requirements";
4472-
abort();
4471+
ABORT("Conformance access path step is missing from requirements");
44734472
}
44744473

44754474
void ASTMangler::appendDependentProtocolConformance(
@@ -4573,9 +4572,10 @@ void ASTMangler::appendAnyProtocolConformance(
45734572
} else if (conformance.isPack()) {
45744573
appendPackProtocolConformance(conformance.getPack(), genericSig);
45754574
} else {
4576-
llvm::errs() << "Bad conformance in mangler: ";
4577-
conformance.dump(llvm::errs());
4578-
abort();
4575+
ABORT([&](auto &out) {
4576+
out << "Bad conformance in mangler: ";
4577+
conformance.dump(out);
4578+
});
45794579
}
45804580
}
45814581

lib/AST/ASTScopePrinting.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void ASTScopeImpl::dumpOneScopeMapLocation(
7272

7373
void ASTScopeImpl::abortWithVerificationError(
7474
llvm::function_ref<void(llvm::raw_ostream &)> messageFn) const {
75-
abortWithPrettyStackTraceMessage([&](auto &out) {
75+
ABORT([&](auto &out) {
7676
out << "ASTScopeImpl verification error in source file '"
7777
<< getSourceFile()->getFilename() << "':\n";
7878
messageFn(out);

lib/AST/AvailabilityScope.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -519,15 +519,16 @@ static void verificationError(
519519
ASTContext &ctx, llvm::StringRef msg,
520520
std::initializer_list<std::pair<const char *, const AvailabilityScope *>>
521521
labelsAndNodes) {
522-
llvm::errs() << msg << "\n";
523-
for (auto pair : labelsAndNodes) {
524-
auto label = std::get<0>(pair);
525-
auto scope = std::get<1>(pair);
526-
llvm::errs() << label << ":\n";
527-
scope->print(llvm::errs(), ctx.SourceMgr);
528-
llvm::errs() << "\n";
529-
}
530-
abort();
522+
ABORT([&](auto &out) {
523+
out << msg << "\n";
524+
for (auto pair : labelsAndNodes) {
525+
auto label = std::get<0>(pair);
526+
auto scope = std::get<1>(pair);
527+
out << label << ":\n";
528+
scope->print(out, ctx.SourceMgr);
529+
out << "\n";
530+
}
531+
});
531532
}
532533

533534
void AvailabilityScope::verify(const AvailabilityScope *parent,

lib/AST/Bridging/MiscBridging.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ static SwiftMetatype declMetatypes[(unsigned)DeclKind::Last_Decl + 1];
6464
SwiftMetatype Decl::getDeclMetatype(DeclKind kind) {
6565
SwiftMetatype metatype = declMetatypes[(unsigned)kind];
6666
if (declMetatypesInitialized && !metatype) {
67-
llvm::errs() << "Decl " << getKindName(kind) << " not registered\n";
68-
abort();
67+
ABORT([&](auto &out) {
68+
out << "Decl " << getKindName(kind) << " not registered";
69+
});
6970
}
7071
return metatype;
7172
}
@@ -83,9 +84,9 @@ void registerBridgedDecl(BridgedStringRef bridgedClassName,
8384
.Default(std::nullopt);
8485

8586
if (!declKind) {
86-
llvm::errs() << "Unknown Decl class " << bridgedClassName.unbridged()
87-
<< "\n";
88-
abort();
87+
ABORT([&](auto &out) {
88+
out << "Unknown Decl class " << bridgedClassName.unbridged();
89+
});
8990
}
9091
declMetatypes[(unsigned)declKind.value()] = metatype;
9192
}

lib/AST/Expr.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1994,9 +1994,10 @@ unsigned AbstractClosureExpr::getDiscriminator() const {
19941994
}
19951995

19961996
if (getRawDiscriminator() == InvalidDiscriminator) {
1997-
llvm::errs() << "Closure does not have an assigned discriminator:\n";
1998-
dump(llvm::errs());
1999-
abort();
1997+
ABORT([&](auto &out) {
1998+
out << "Closure does not have an assigned discriminator:\n";
1999+
this->dump(out);
2000+
});
20002001
}
20012002

20022003
return getRawDiscriminator();

0 commit comments

Comments
 (0)