Skip to content

Commit d06c5ab

Browse files
committed
Explain which assertion failed during consteval
1 parent 834d426 commit d06c5ab

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
@@ -162,6 +162,8 @@ def err_ice_too_large : Error<
162162
"integer constant expression evaluates to value %0 that cannot be "
163163
"represented in a %1-bit %select{signed|unsigned}2 integer type">;
164164
def err_expr_not_string_literal : Error<"expression is not a string literal">;
165+
def note_constexpr_assert_failed : Note<
166+
"assertion failed in constant evaluation: '%0'">;
165167

166168
// Semantic analysis of constant literals.
167169
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
@@ -8409,6 +8409,17 @@ class ExprEvaluatorBase
84098409
return false;
84108410
}
84118411

8412+
// If an assertion fails during constant evaluation, give a specific note explaining that
8413+
if (FD->getName() == "__assert_fail") {
8414+
const Expr *AssertionExpr = E->getArg(0);
8415+
const StringLiteral *AssertionText = dyn_cast<StringLiteral>(AssertionExpr->IgnoreParens()->IgnoreParenImpCasts());
8416+
8417+
Info.FFDiag(E->getBeginLoc(), diag::note_constexpr_assert_failed)
8418+
<< (AssertionText ? AssertionText->getString() : "<unknown assertion>");
8419+
8420+
return false;
8421+
}
8422+
84128423
SmallVector<QualType, 4> CovariantAdjustmentPath;
84138424
if (This) {
84148425
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 constant evaluation: '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)