Skip to content

Commit ec2d6ad

Browse files
authored
[clang] introduce constexpr step limit opt-out (llvm#160440)
To address @AaronBallman's feedback from llvm#143785 this patch implements an explicit opt-out for `-fconstexpr-steps` by setting `-fconstexpr-steps=0`. This does not change any defaults, but gives users an easy way to opt out of this limit altogether (and instead let the compiler reach the system's resource limits). Currently users set `constexpr-steps` to some arbitrary high number (and I mean _arbitrary_ - see the tables in the previous PR). This isn't actually opting out of the limit though - you're still bound by the upper bound of the counter's type. If you have enough resources to evaluate more than 18446744073709551615 steps that's bad news. In any case, `=0` conveys the intent clearer. This is in line with how we handle other flags, ie `-ftemplate-backtrace-limit` or `-ferror-limit`.
1 parent 1820102 commit ec2d6ad

File tree

5 files changed

+10
-5
lines changed

5 files changed

+10
-5
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ Deprecated Compiler Flags
286286
Modified Compiler Flags
287287
-----------------------
288288
- The `-gkey-instructions` compiler flag is now enabled by default when DWARF is emitted for plain C/C++ and optimizations are enabled. (#GH149509)
289+
- The `-fconstexpr-steps` compiler flag now accepts value `0` to opt out of this limit. (#GH160440)
289290

290291
Removed Compiler Flags
291292
-------------------------

clang/docs/UsersManual.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4036,7 +4036,7 @@ Controlling implementation limits
40364036
Sets the limit for the number of full-expressions evaluated in a single
40374037
constant expression evaluation. This also controls the maximum size
40384038
of array and dynamic array allocation that can be constant evaluated.
4039-
The default is 1048576.
4039+
The default is 1048576, and the limit can be disabled with `-fconstexpr-steps=0`.
40404040

40414041
.. option:: -ftemplate-depth=N
40424042

clang/include/clang/Driver/Options.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2047,7 +2047,7 @@ def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>,
20472047
MarshallingInfoInt<LangOpts<"ConstexprCallDepth">, "512">;
20482048
def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>,
20492049
Visibility<[ClangOption, CC1Option]>,
2050-
HelpText<"Set the maximum number of steps in constexpr function evaluation">,
2050+
HelpText<"Set the maximum number of steps in constexpr function evaluation (0 = no limit)">,
20512051
MarshallingInfoInt<LangOpts<"ConstexprStepLimit">, "1048576">;
20522052
def fexperimental_new_constant_interpreter : Flag<["-"], "fexperimental-new-constant-interpreter">, Group<f_Group>,
20532053
HelpText<"Enable the experimental new constant interpreter">,

clang/lib/AST/ByteCode/Interp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3699,7 +3699,7 @@ inline bool CheckDestruction(InterpState &S, CodePtr OpPC) {
36993699

37003700
inline bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems) {
37013701
uint64_t Limit = S.getLangOpts().ConstexprStepLimit;
3702-
if (NumElems > Limit) {
3702+
if (Limit != 0 && NumElems > Limit) {
37033703
S.FFDiag(S.Current->getSource(OpPC),
37043704
diag::note_constexpr_new_exceeds_limits)
37053705
<< NumElems << Limit;

clang/lib/AST/ExprConstant.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,7 @@ namespace {
990990
// of arrays to avoid exhausting the system resources, as initialization
991991
// of each element is likely to take some number of steps anyway.
992992
uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
993-
if (ElemCount > Limit) {
993+
if (Limit != 0 && ElemCount > Limit) {
994994
if (Diag)
995995
FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
996996
<< ElemCount << Limit;
@@ -1016,6 +1016,9 @@ namespace {
10161016
}
10171017

10181018
bool nextStep(const Stmt *S) {
1019+
if (Ctx.getLangOpts().ConstexprStepLimit == 0)
1020+
return true;
1021+
10191022
if (!StepsLeft) {
10201023
FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
10211024
return false;
@@ -1186,7 +1189,8 @@ namespace {
11861189
/// Should we continue evaluation as much as possible after encountering a
11871190
/// construct which can't be reduced to a value?
11881191
bool keepEvaluatingAfterFailure() const override {
1189-
if (!StepsLeft)
1192+
uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
1193+
if (Limit != 0 && !StepsLeft)
11901194
return false;
11911195

11921196
switch (EvalMode) {

0 commit comments

Comments
 (0)