From a9d97d453d6d6587ec28aee9381020b1cbd54412 Mon Sep 17 00:00:00 2001 From: Tsche Date: Wed, 24 Sep 2025 07:09:29 +0200 Subject: [PATCH 1/5] [clang] introduce constexpr step limit opt-out --- clang/docs/UsersManual.rst | 2 +- clang/lib/AST/ByteCode/Interp.h | 3 +++ clang/lib/AST/ExprConstant.cpp | 5 ++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index a8bbf146431ea..1a062475728dd 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -4028,7 +4028,7 @@ Controlling implementation limits Sets the limit for the number of full-expressions evaluated in a single constant expression evaluation. This also controls the maximum size of array and dynamic array allocation that can be constant evaluated. - The default is 1048576. + The default is 1048576, and the limit can be disabled with `-fconstexpr-steps=0`.. .. option:: -ftemplate-depth=N diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index b3b4b998439cc..deba2d294abe9 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -3686,6 +3686,9 @@ inline bool CheckDestruction(InterpState &S, CodePtr OpPC) { inline bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems) { uint64_t Limit = S.getLangOpts().ConstexprStepLimit; + if (Limit == 0) + return true; + if (NumElems > Limit) { S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_new_exceeds_limits) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index d10e2afeb2341..0fe3fce5b64a8 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -990,7 +990,7 @@ namespace { // of arrays to avoid exhausting the system resources, as initialization // of each element is likely to take some number of steps anyway. uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit; - if (ElemCount > Limit) { + if (Limit != 0 && ElemCount > Limit) { if (Diag) FFDiag(Loc, diag::note_constexpr_new_exceeds_limits) << ElemCount << Limit; @@ -1016,6 +1016,9 @@ namespace { } bool nextStep(const Stmt *S) { + if (Ctx.getLangOpts().ConstexprStepLimit == 0) + return true; + if (!StepsLeft) { FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded); return false; From 40fe30d71f3a0fc45662267112cad978e27c7df6 Mon Sep 17 00:00:00 2001 From: Tsche Date: Wed, 24 Sep 2025 17:21:57 +0200 Subject: [PATCH 2/5] [clang] add help text for constexpr step limit opt-out --- clang/include/clang/Driver/Options.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 77f19a240a7f9..ddf984a5ab447 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2045,7 +2045,7 @@ def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group, MarshallingInfoInt, "512">; def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group, Visibility<[ClangOption, CC1Option]>, - HelpText<"Set the maximum number of steps in constexpr function evaluation">, + HelpText<"Set the maximum number of steps in constexpr function evaluation (0 = no limit)">, MarshallingInfoInt, "1048576">; def fexperimental_new_constant_interpreter : Flag<["-"], "fexperimental-new-constant-interpreter">, Group, HelpText<"Enable the experimental new constant interpreter">, From 747856a3998040dec8de031d071a8ba952aa16e6 Mon Sep 17 00:00:00 2001 From: Tsche Date: Wed, 24 Sep 2025 18:19:34 +0200 Subject: [PATCH 3/5] [clang] add release note for constexpr step limit opt-out --- clang/docs/ReleaseNotes.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 70c82b090107a..50b5f2cb3ee16 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -258,6 +258,7 @@ Deprecated Compiler Flags Modified Compiler Flags ----------------------- - The `-gkey-instructions` compiler flag is now enabled by default when DWARF is emitted for plain C/C++ and optimizations are enabled. (#GH149509) +- The `-fconstexpr-steps` compiler flag now accepts value `0` to opt out of this limit. (#GH160440) Removed Compiler Flags ------------------------- From 1eb7f6dcf9bb1485b12346fba6cd7dba515d5426 Mon Sep 17 00:00:00 2001 From: Tsche Date: Mon, 13 Oct 2025 09:27:39 +0200 Subject: [PATCH 4/5] [clang] add step limit opt-out to keepEvaluatingAfterFailure, clean up CheckArraySize --- clang/lib/AST/ByteCode/Interp.h | 5 +---- clang/lib/AST/ExprConstant.cpp | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index deba2d294abe9..76856ad35b3d0 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -3686,10 +3686,7 @@ inline bool CheckDestruction(InterpState &S, CodePtr OpPC) { inline bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems) { uint64_t Limit = S.getLangOpts().ConstexprStepLimit; - if (Limit == 0) - return true; - - if (NumElems > Limit) { + if (Limit != 0 && NumElems > Limit) { S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_new_exceeds_limits) << NumElems << Limit; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 0fe3fce5b64a8..aad6f5eed41f5 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1189,7 +1189,8 @@ namespace { /// Should we continue evaluation as much as possible after encountering a /// construct which can't be reduced to a value? bool keepEvaluatingAfterFailure() const override { - if (!StepsLeft) + uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit; + if (Limit != 0 && !StepsLeft) return false; switch (EvalMode) { From e763cb6f6872143739ce5998ec50acd961e0a528 Mon Sep 17 00:00:00 2001 From: Tsche Date: Mon, 13 Oct 2025 09:28:19 +0200 Subject: [PATCH 5/5] [clang] remove accidental full stop at the end of the sentence --- clang/docs/UsersManual.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 1a062475728dd..5872f7ac3b724 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -4028,7 +4028,7 @@ Controlling implementation limits Sets the limit for the number of full-expressions evaluated in a single constant expression evaluation. This also controls the maximum size of array and dynamic array allocation that can be constant evaluated. - The default is 1048576, and the limit can be disabled with `-fconstexpr-steps=0`.. + The default is 1048576, and the limit can be disabled with `-fconstexpr-steps=0`. .. option:: -ftemplate-depth=N