https://github.com/jj-marr updated https://github.com/llvm/llvm-project/pull/130458
>From d61892d8546944000118ad0312886da75cd6509b Mon Sep 17 00:00:00 2001 From: JJ Marr <jjm...@gmail.com> Date: Sat, 8 Mar 2025 22:00:45 -0500 Subject: [PATCH] Explain which assertion failed during consteval --- .../clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/lib/AST/ExprConstant.cpp | 11 ++++++++++ clang/test/SemaCXX/consteval_assert.cpp | 20 +++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 clang/test/SemaCXX/consteval_assert.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 21be7c358a61d..ff5f88d6ac572 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -107,6 +107,8 @@ def err_ice_too_large : Error< "integer constant expression evaluates to value %0 that cannot be " "represented in a %1-bit %select{signed|unsigned}2 integer type">; def err_expr_not_string_literal : Error<"expression is not a string literal">; +def note_constexpr_assert_failed : Note< + "assertion failed in consteval context: '%0'">; // Semantic analysis of constant literals. def ext_predef_outside_function : Warning< diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index d9a1e5bb42343..7013f0b143a0a 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -8361,6 +8361,17 @@ class ExprEvaluatorBase return false; } + // If an assertion fails during constant evaluation, give a specific note explaining that + if (FD->getName() == "__assert_fail") { + const Expr *AssertionExpr = E->getArg(0); + const StringLiteral *AssertionText = dyn_cast<StringLiteral>(AssertionExpr->IgnoreParens()->IgnoreParenImpCasts()); + + Info.FFDiag(E->getBeginLoc(), diag::note_constexpr_assert_failed) + << (AssertionText ? AssertionText->getString() : "<unknown assertion>"); + + return false; + } + SmallVector<QualType, 4> CovariantAdjustmentPath; if (This) { auto *NamedMember = dyn_cast<CXXMethodDecl>(FD); diff --git a/clang/test/SemaCXX/consteval_assert.cpp b/clang/test/SemaCXX/consteval_assert.cpp new file mode 100644 index 0000000000000..94ca9ffd4888d --- /dev/null +++ b/clang/test/SemaCXX/consteval_assert.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -std=c++23 -verify=expected,cxx20_plus %s + +#ifdef __ASSERT_FUNCTION +#undef __ASSERT_FUNCTION +#endif +extern "C" void __assert_fail(const char*, const char*, unsigned, const char*); + +#define assert(cond) \ + ((cond) ? (void)0 : __assert_fail(#cond, __FILE__, __LINE__, __func__)) + +consteval int square(int x) { + int result = x * x; + assert(result == 42); // expected-note {{assertion failed in consteval context: 'result == 42'}} + return result; +} + +void test() { + auto val = square(2); // expected-note {{in call to 'square(2)'}} \ + // expected-error {{call to consteval function 'square' is not a constant expression}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits