Skip to content

Commit d61892d

Browse files
committed
Explain which assertion failed during consteval
1 parent d08cf79 commit d61892d

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ def err_ice_too_large : Error<
107107
"integer constant expression evaluates to value %0 that cannot be "
108108
"represented in a %1-bit %select{signed|unsigned}2 integer type">;
109109
def err_expr_not_string_literal : Error<"expression is not a string literal">;
110+
def note_constexpr_assert_failed : Note<
111+
"assertion failed in consteval context: '%0'">;
110112

111113
// Semantic analysis of constant literals.
112114
def ext_predef_outside_function : Warning<

clang/lib/AST/ExprConstant.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8361,6 +8361,17 @@ class ExprEvaluatorBase
83618361
return false;
83628362
}
83638363

8364+
// If an assertion fails during constant evaluation, give a specific note explaining that
8365+
if (FD->getName() == "__assert_fail") {
8366+
const Expr *AssertionExpr = E->getArg(0);
8367+
const StringLiteral *AssertionText = dyn_cast<StringLiteral>(AssertionExpr->IgnoreParens()->IgnoreParenImpCasts());
8368+
8369+
Info.FFDiag(E->getBeginLoc(), diag::note_constexpr_assert_failed)
8370+
<< (AssertionText ? AssertionText->getString() : "<unknown assertion>");
8371+
8372+
return false;
8373+
}
8374+
83648375
SmallVector<QualType, 4> CovariantAdjustmentPath;
83658376
if (This) {
83668377
auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %clang_cc1 -std=c++23 -verify=expected,cxx20_plus %s
2+
3+
#ifdef __ASSERT_FUNCTION
4+
#undef __ASSERT_FUNCTION
5+
#endif
6+
extern "C" void __assert_fail(const char*, const char*, unsigned, const char*);
7+
8+
#define assert(cond) \
9+
((cond) ? (void)0 : __assert_fail(#cond, __FILE__, __LINE__, __func__))
10+
11+
consteval int square(int x) {
12+
int result = x * x;
13+
assert(result == 42); // expected-note {{assertion failed in consteval context: 'result == 42'}}
14+
return result;
15+
}
16+
17+
void test() {
18+
auto val = square(2); // expected-note {{in call to 'square(2)'}} \
19+
// expected-error {{call to consteval function 'square' is not a constant expression}}
20+
}

0 commit comments

Comments
 (0)