Skip to content

Commit 37e5f30

Browse files
committed
Add some basic assertion handling control options
1 parent f09fb7d commit 37e5f30

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

include/swift/Basic/Assertions.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
} while (0)
4545

4646
// Function that reports the actual failure when it occurs.
47-
[[noreturn]] void ASSERT_failure(const char *expr, const char *file, int line, const char *func);
47+
void ASSERT_failure(const char *expr, const char *file, int line, const char *func);
4848

4949
// ================================ Conditional Asserts ================================
5050

@@ -171,4 +171,11 @@ extern int CONDITIONAL_ASSERT_Global_enable_flag;
171171
#define SWIFT_ASSERT_ONLY_DECL DEBUG_ASSERT_DECL
172172
#define SWIFT_ASSERT_ONLY DEBUG_ASSERT_EXPR
173173

174+
// ================================ Utility and Helper Functions ================================
175+
176+
// Utility function to print out help information for
177+
// various command-line options that affect the assertion
178+
// behavior.
179+
void ASSERT_help();
180+
174181
#endif // SWIFT_BASIC_ASSERTIONS_H

lib/Basic/Assertions.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,28 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17+
#include "llvm/Support/CommandLine.h"
1718
#include "swift/Basic/Assertions.h"
1819
#undef NDEBUG
1920
#include <cassert>
2021
#include <iostream>
2122

23+
llvm::cl::opt<bool> AssertContinue(
24+
"assert-continue", llvm::cl::init(false),
25+
llvm::cl::desc("Do not stop on an assertion failure"));
26+
27+
llvm::cl::opt<bool> AssertHelp(
28+
"assert-help", llvm::cl::init(false),
29+
llvm::cl::desc("Print help for managing assertions"));
30+
2231
int CONDITIONAL_ASSERT_Global_enable_flag =
2332
#ifdef NDEBUG
2433
0; // Default to `off` in release builds
2534
#else
2635
0; // TODO: Default to `on` in debug builds
2736
#endif
2837

29-
[[noreturn]] void ASSERT_failure(const char *expr, const char *file, int line, const char *func) {
38+
void ASSERT_failure(const char *expr, const char *file, int line, const char *func) {
3039
// Only print the last component of `file`
3140
const char *f = file;
3241
for (const char *p = file; *p != '\0'; p++) {
@@ -35,6 +44,14 @@ int CONDITIONAL_ASSERT_Global_enable_flag =
3544
f = p + 1;
3645
}
3746
}
47+
48+
if (AssertHelp) {
49+
ASSERT_help();
50+
} else {
51+
std::cerr << "Assertion help: -Xllvm -assert-help" << std::endl;
52+
}
53+
54+
3855
// Format here matches that used by `assert` on macOS:
3956
std::cerr
4057
<< "Assertion failed: "
@@ -43,9 +60,30 @@ int CONDITIONAL_ASSERT_Global_enable_flag =
4360
<< "file " << f << ", "
4461
<< "line " << line << "."
4562
<< std::endl;
63+
64+
if (AssertContinue) {
65+
std::cerr << "Continuing after failed assertion (-Xllvm -assert-continue)" << std::endl;
66+
return;
67+
}
68+
4669
abort();
4770
}
4871

72+
void ASSERT_help() {
73+
static int ASSERT_help_shown = 0;
74+
if (ASSERT_help_shown) {
75+
return;
76+
}
77+
ASSERT_help_shown = 1;
78+
79+
std::cerr << std::endl;
80+
std::cerr << "Control assertion behavior with one or more of the following options:" << std::endl;
81+
std::cerr << std::endl;
82+
std::cerr << " -Xllvm -assert-continue" << std::endl;
83+
std::cerr << " Continue after any failed assertion" << std::endl;
84+
std::cerr << std::endl;
85+
}
86+
4987
// This has to be callable in the same way as the macro version,
5088
// so we can't put it inside a namespace.
5189
#undef CONDITIONAL_ASSERT_enabled

0 commit comments

Comments
 (0)