https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/212091
>From 68ce5b5ca08b846ed9426232846a40181d84f3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Sun, 26 Jul 2026 07:15:52 +0200 Subject: [PATCH] diags --- clang/include/clang/Basic/DiagnosticASTKinds.td | 7 ++++--- clang/lib/AST/ByteCode/InterpHelpers.h | 3 ++- clang/lib/AST/ByteCode/InterpState.cpp | 4 +++- clang/lib/AST/ByteCode/State.cpp | 6 ++++++ clang/lib/AST/ByteCode/State.h | 1 + clang/lib/AST/ExprConstant.cpp | 10 +++++++--- clang/test/AST/ByteCode/constexpr-steps.cpp | 6 ++++-- clang/test/AST/ByteCode/dynalloc-limits.cpp | 6 ++++-- .../SemaCXX/constexpr-function-recovery-crash.cpp | 15 ++++++++++----- clang/test/SemaCXX/constexpr-steps.cpp | 3 ++- .../SemaCXX/cxx2a-constexpr-dynalloc-limits.cpp | 9 ++++++--- clang/test/SemaCXX/cxx2c-expansion-stmts.cpp | 1 + 12 files changed, 50 insertions(+), 21 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index f86f0157b2b1f..c4582a3a9d641 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -170,7 +170,7 @@ def note_constexpr_depth_limit_exceeded : Note< def note_constexpr_call_limit_exceeded : Note< "constexpr evaluation hit maximum call limit">; def note_constexpr_step_limit_exceeded : Note< - "constexpr evaluation hit maximum step limit; possible infinite loop?">; + "constexpr evaluation hit maximum step limit of %0; possible infinite loop?">; def note_constexpr_heap_alloc_limit_exceeded : Note< "constexpr evaluation hit maximum heap allocation limit">; def note_constexpr_this : Note< @@ -355,8 +355,9 @@ def note_constexpr_new_negative : Note< def note_constexpr_new_too_large : Note< "cannot allocate array; evaluated array bound %0 is too large">; def note_constexpr_new_exceeds_limits : Note< - "cannot allocate array; evaluated array bound %0 exceeds the limit (%1); " - "use '-fconstexpr-steps' to increase this limit">; + "cannot allocate array; evaluated array bound %0 exceeds the limit (%1)">; +def note_constexpr_steps : Note< + "use -fconstexpr-steps= to increase this limit (=0 will remove the limit)">; def note_constexpr_new_too_small : Note< "cannot allocate array; evaluated array bound %0 is too small to hold " "%1 explicitly initialized elements">; diff --git a/clang/lib/AST/ByteCode/InterpHelpers.h b/clang/lib/AST/ByteCode/InterpHelpers.h index 4d908d1e44546..1df570ac971c4 100644 --- a/clang/lib/AST/ByteCode/InterpHelpers.h +++ b/clang/lib/AST/ByteCode/InterpHelpers.h @@ -94,8 +94,9 @@ inline bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems) { uint64_t Limit = S.getLangOpts().ConstexprStepLimit; if (Limit != 0 && NumElems > Limit) { S.FFDiag(S.Current->getSource(OpPC), - diag::note_constexpr_new_exceeds_limits) + diag::note_constexpr_new_exceeds_limits, 1) << NumElems << Limit; + S.Note(S.Current->getSource(OpPC), diag::note_constexpr_steps); return false; } return true; diff --git a/clang/lib/AST/ByteCode/InterpState.cpp b/clang/lib/AST/ByteCode/InterpState.cpp index f6338cda56e34..6ac1b2610dd09 100644 --- a/clang/lib/AST/ByteCode/InterpState.cpp +++ b/clang/lib/AST/ByteCode/InterpState.cpp @@ -165,6 +165,8 @@ bool InterpState::noteStep(CodePtr OpPC) { if (StepsLeft != 0) return true; - FFDiag(Current->getSource(OpPC), diag::note_constexpr_step_limit_exceeded); + FFDiag(Current->getSource(OpPC), diag::note_constexpr_step_limit_exceeded, 1) + << getLangOpts().ConstexprStepLimit; + Note(Current->getSource(OpPC), diag::note_constexpr_steps); return false; } diff --git a/clang/lib/AST/ByteCode/State.cpp b/clang/lib/AST/ByteCode/State.cpp index e62b77272046c..38384bae23f57 100644 --- a/clang/lib/AST/ByteCode/State.cpp +++ b/clang/lib/AST/ByteCode/State.cpp @@ -69,6 +69,12 @@ OptionalDiagnostic State::Note(SourceLocation Loc, diag::kind DiagId) { return OptionalDiagnostic(&addDiag(Loc, DiagId)); } +OptionalDiagnostic State::Note(SourceInfo SI, diag::kind DiagId) { + if (!hasActiveDiagnostic()) + return OptionalDiagnostic(); + return OptionalDiagnostic(&addDiag(SI.getLoc(), DiagId)); +} + void State::addNotes(ArrayRef<PartialDiagnosticAt> Diags) { if (hasActiveDiagnostic()) llvm::append_range(*EvalStatus.Diag, Diags); diff --git a/clang/lib/AST/ByteCode/State.h b/clang/lib/AST/ByteCode/State.h index df3afdf8cbc24..df91132c48472 100644 --- a/clang/lib/AST/ByteCode/State.h +++ b/clang/lib/AST/ByteCode/State.h @@ -162,6 +162,7 @@ class State { /// Add a note to a prior diagnostic. OptionalDiagnostic Note(SourceLocation Loc, diag::kind DiagId); + OptionalDiagnostic Note(SourceInfo Loc, diag::kind DiagId); /// Add a stack of notes to a prior diagnostic. void addNotes(ArrayRef<PartialDiagnosticAt> Diags); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 574dd8b04e779..3c715d80bb691 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -974,9 +974,11 @@ namespace { // of each element is likely to take some number of steps anyway. uint64_t Limit = getLangOpts().ConstexprStepLimit; if (Limit != 0 && ElemCount > Limit) { - if (Diag) - FFDiag(Loc, diag::note_constexpr_new_exceeds_limits) + if (Diag) { + FFDiag(Loc, diag::note_constexpr_new_exceeds_limits, 1) << ElemCount << Limit; + Note(Loc, diag::note_constexpr_steps); + } return false; } return true; @@ -1003,7 +1005,9 @@ namespace { return true; if (!StepsLeft) { - FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded); + FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded, 1) + << getLangOpts().ConstexprStepLimit; + Note(S->getBeginLoc(), diag::note_constexpr_steps); return false; } --StepsLeft; diff --git a/clang/test/AST/ByteCode/constexpr-steps.cpp b/clang/test/AST/ByteCode/constexpr-steps.cpp index bd461547032a9..3ba6b1cb3adcd 100644 --- a/clang/test/AST/ByteCode/constexpr-steps.cpp +++ b/clang/test/AST/ByteCode/constexpr-steps.cpp @@ -2,14 +2,16 @@ constexpr int foo() { // expected-error {{never produces a constant expression}} - while (1) {} // expected-note 2{{constexpr evaluation hit maximum step limit}} + while (1) {} // expected-note 2{{constexpr evaluation hit maximum step limit}} \ + // expected-note 2{{use -fconstexpr-steps}} return 0; } static_assert (foo() == 0, ""); // expected-error {{not an integral constant expression}} \ // expected-note {{in call to}} constexpr void addr() { // expected-error {{never produces a constant expression}} - for (;;) // expected-note 2{{constexpr evaluation hit maximum step limit}} + for (;;) // expected-note 2{{constexpr evaluation hit maximum step limit}} \ + // expected-note 2{{use -fconstexpr-steps}} ; } static_assert((addr(), 1) == 1); // expected-error {{not an integral constant expression}} \ diff --git a/clang/test/AST/ByteCode/dynalloc-limits.cpp b/clang/test/AST/ByteCode/dynalloc-limits.cpp index ed2d4faf974b1..85d66ac88ee2c 100644 --- a/clang/test/AST/ByteCode/dynalloc-limits.cpp +++ b/clang/test/AST/ByteCode/dynalloc-limits.cpp @@ -54,7 +54,8 @@ constexpr std::size_t s = S<std::size_t>(~0UL)[42]; // both-error {{constexpr va constexpr std::size_t ssmall = S<std::size_t>(100)[42]; constexpr std::size_t s5 = S<std::size_t>(1025)[42]; // both-error {{constexpr variable 's5' must be initialized by a constant expression}} \ - // both-note@#alloc {{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024); use '-fconstexpr-steps' to increase this limit}} \ + // both-note@#alloc {{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024)}} \ + // both-note@#alloc {{use -fconstexpr-steps}} \ // both-note@#call {{in call to 'this->alloc.allocate(1025)'}} \ // both-note {{in call}} @@ -62,7 +63,8 @@ constexpr std::size_t s5 = S<std::size_t>(1025)[42]; // both-error {{constexpr v template <auto N> constexpr int stack_array() { - [[maybe_unused]] char BIG[N] = {1}; // both-note {{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024)}} + [[maybe_unused]] char BIG[N] = {1}; // both-note {{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024)}} \ + // both-note {{use -fconstexpr-steps}} return BIG[N-1]; } diff --git a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp index de8fe057893d5..016bd188ac9f7 100644 --- a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp +++ b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp @@ -36,7 +36,8 @@ constexpr int test4() { constexpr int test5() { // expected-error {{constexpr function never produce}} for (;; a++); // expected-error {{use of undeclared identifier}} \ - expected-note {{constexpr evaluation hit maximum step limit; possible infinite loop?}} + expected-note {{constexpr evaluation hit maximum step limit of 1048576; possible infinite loop?}} \ + expected-note {{use -fconstexpr-steps}} return 1; } @@ -44,7 +45,8 @@ constexpr int test6() { // expected-error {{constexpr function never produce}} int n = 0; switch (n) { for (;; a++) { // expected-error {{use of undeclared identifier}} - case 0:; // expected-note {{constexpr evaluation hit maximum step limit; possible infinite loop?}} + case 0:; // expected-note {{constexpr evaluation hit maximum step limit of 1048576; possible infinite loop?}} \ + // expected-note {{use -fconstexpr-steps}} } } return 0; @@ -91,7 +93,8 @@ TEST_EVALUATE(SwitchCondValDep, switch (invalid_value) { default: break; }); TEST_EVALUATE(For, for (!!){}); // expected-error + {{}} // FIXME: should bail out instead of looping. // expected-note@-2 + {{infinite loop}} - // expected-note@-3 {{in call}} + // expected-note@-3 + {{use -fconstexpr-steps}} + // expected-note@-4 {{in call}} TEST_EVALUATE(ForRange, for (auto x : !!){}); // expected-error + {{}} TEST_EVALUATE(While, while (!!){}); // expected-error + {{}} TEST_EVALUATE(DoWhile, do {} while (!!);); // expected-error + {{}} @@ -101,9 +104,11 @@ TEST_EVALUATE(If, if (!!){};); // expected-error + {{}} TEST_EVALUATE(IfInit, if (auto x = !!; 1){};);// expected-error + {{}} TEST_EVALUATE(ForInit, for (!!;;){};);// expected-error + {{}} // expected-note@-1 + {{infinite loop}} - // expected-note@-2 {{in call}} + // expected-note@-2 + {{use -fconstexpr-steps}} + // expected-note@-3 {{in call}} TEST_EVALUATE(ForCond, for (; !!;){};);// expected-error + {{}} TEST_EVALUATE(ForInc, for (;; !!){};);// expected-error + {{}} // expected-note@-1 + {{infinite loop}} - // expected-note@-2 {{in call}} + // expected-note@-2 + {{use -fconstexpr-steps}} + // expected-note@-3 {{in call}} TEST_EVALUATE(ForCondUnDef, for (;some_cond;){};); // expected-error + {{}} diff --git a/clang/test/SemaCXX/constexpr-steps.cpp b/clang/test/SemaCXX/constexpr-steps.cpp index 5ec4aa82b8cac..03ce9f05ebcb4 100644 --- a/clang/test/SemaCXX/constexpr-steps.cpp +++ b/clang/test/SemaCXX/constexpr-steps.cpp @@ -10,7 +10,8 @@ // - One for the 'return' statemnet constexpr bool steps(int n) { for (int k = 0; k != n; ++k) {} - return true; // expected-note {{step limit}} + return true; // expected-note {{step limit}} \ + // expected-note {{use -fconstexpr-steps}} } static_assert(steps((MAX - 4)), ""); // ok diff --git a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc-limits.cpp b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc-limits.cpp index 8bcb4d45d4af8..7537b47780aeb 100644 --- a/clang/test/SemaCXX/cxx2a-constexpr-dynalloc-limits.cpp +++ b/clang/test/SemaCXX/cxx2a-constexpr-dynalloc-limits.cpp @@ -58,14 +58,16 @@ constexpr std::size_t ssmall = S<std::size_t>(100)[42]; // We can allocate this array but we hikt the number of steps constexpr std::size_t s4 = S<std::size_t>(1024)[42]; // expected-error {{constexpr variable 's4' must be initialized by a constant expression}} \ - // expected-note@#construct {{constexpr evaluation hit maximum step limit; possible infinite loop?}} \ + // expected-note@#construct {{constexpr evaluation hit maximum step limit of 1024; possible infinite loop?}} \ + // expected-note@#construct {{use -fconstexpr-steps}} \ // expected-note@#construct_call {{in call}} \ // expected-note {{in call}} constexpr std::size_t s5 = S<std::size_t>(1025)[42]; // expected-error{{constexpr variable 's5' must be initialized by a constant expression}} \ - // expected-note@#alloc {{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024); use '-fconstexpr-steps' to increase this limit}} \ + // expected-note@#alloc {{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024)}} \ + // expected-note@#alloc {{use -fconstexpr-steps}} \ // expected-note@#call {{in call to 'this->alloc.allocate(1025)'}} \ // expected-note {{in call}} @@ -75,7 +77,8 @@ constexpr std::size_t s5 = S<std::size_t>(1025)[42]; // expected-error{{constexp template <auto N> constexpr int stack_array() { - [[maybe_unused]] char BIG[N] = {1}; // expected-note 3{{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024); use '-fconstexpr-steps' to increase this limit}} + [[maybe_unused]] char BIG[N] = {1}; // expected-note 3{{cannot allocate array; evaluated array bound 1025 exceeds the limit (1024)}} \ + // expected-note 3{{use -fconstexpr-steps}} return BIG[N-1]; } diff --git a/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp b/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp index fb93cdf588f6c..dd450a8f1b76c 100644 --- a/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp +++ b/clang/test/SemaCXX/cxx2c-expansion-stmts.cpp @@ -177,6 +177,7 @@ void negative_size() { static constexpr NegativeSize n; template for (auto x : n) g(x); // expected-error {{expansion statement size is not a constant expression}} \ old-interp-note {{constexpr evaluation hit maximum step limit}} \ + old-interp-note {{use -fconstexpr-steps}} \ new-interp-note {{cannot refer to element 5 of array of 4 elements in a constant expression}} \ expected-note {{in call to}} template for (constexpr auto x : n) g(x); // expected-error {{expansion statement size is not a constant expression}} \ _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
