llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: None (Tsche)

<details>
<summary>Changes</summary>

Currently clang limits the number of constant evaluation steps to 1'048'576 (or 
2^20) by default. This default comes from 
[[implimits]/1.39](https://eel.is/c++draft/implimits#<!-- -->1.39).

This limit is easily reached - for example in libc++ tests we override this 
default in many places:
&lt;details&gt;
&lt;summary&gt;overrides in libc++ tests&lt;/summary&gt;

| Step Limit | Test |
|----------------|--------|
| 2000000 | 
libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp |
| 2000000 | 
libcxx/test/std/algorithms/alg.nonmodifying/alg.contains/ranges.contains_subrange.pass.cpp
 |
| 2000000 | 
libcxx/test/std/containers/sequences/vector/vector.modifiers/append_range.pass.cpp
 |
| 2000000 | 
libcxx/test/std/containers/sequences/vector/vector.modifiers/assign_range.pass.cpp
 |
| 2000000 | 
libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_range.pass.cpp
 |
| 2000000 | 
libcxx/test/std/containers/sequences/vector.bool/append_range.pass.cpp |
| 2000000 | 
libcxx/test/std/containers/sequences/vector.bool/assign_range.pass.cpp |
| 2000000 | 
libcxx/test/std/containers/sequences/vector.bool/insert_range.pass.cpp |
| 2000000 | 
libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp
 |
| 2000000 | 
libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp
 |
| 2000000 | 
libcxx/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp |
| 3000000 | 
libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_range.pass.cpp
 |
| 9000000 | 
libcxx/test/libcxx/input.output/iostream.format/print.fun/transcoding.pass.cpp |
| 9000000 | 
libcxx/test/std/containers/sequences/vector/vector.modifiers/emplace.pass.cpp |
| 9000000 | 
libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string.string_view.pass.cpp
 |
| 10000000 | 
libcxx/test/std/strings/basic.string/string.modifiers/string_replace/replace_with_range.pass.cpp
 |
| 12712420 | 
libcxx/test/std/utilities/charconv/charconv.from.chars/integral.roundtrip.pass.cpp
 |
| 12712420 | 
libcxx/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp |
| 12712420 | 
libcxx/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp |
| 15000000 | 
libcxx/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp 
|
| 15000000 | 
libcxx/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp |
| 15000000 | 
libcxx/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp
 |
| 20000000 | 
libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp |
| 20000000 | 
libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp |
| 20000000 | libcxx/test/std/algorithms/alg.nonmodifying/alg.find/find.pass.cpp 
|
| 20000000 | 
libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp |
| 20000000 | 
libcxx/test/std/containers/sequences/forwardlist/forwardlist.modifiers/insert_range_after.pass.cpp
 |
| 50000000 | 
libcxx/test/std/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp |
| 200000000 | 
libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort_comp.pass.cpp
 |
| 200000000 | 
libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
 |

&lt;/details&gt;

In libc++ tests that override both `-fconstexpr-steps` and GCC's 
`-fconstexpr-ops-limit`, we see a factor of 0.25 applied in most cases:
&lt;details&gt;
&lt;summary&gt;overrides in libc++ tests&lt;/summary&gt;

| Factor | `-fconstexpr-steps` | `-fconstexpr-ops-limit` | Test |
|--------|---------------------|-------------------------|------|
| 0.14 | 10000000 | 70000000 | 
libcxx/test/std/strings/basic.string/string.modifiers/string_replace/replace_with_range.pass.cpp
 |
| 0.25 | 20000000 | 80000000 | 
libcxx/test/std/algorithms/alg.nonmodifying/alg.count/count.pass.cpp |
| 0.25 | 20000000 | 80000000 | 
libcxx/test/std/algorithms/alg.nonmodifying/alg.count/ranges.count.pass.cpp |
| 0.25 | 20000000 | 80000000 | 
libcxx/test/std/algorithms/alg.nonmodifying/alg.find/find.pass.cpp |
| 0.25 | 20000000 | 80000000 | 
libcxx/test/std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp |
| 0.25 | 12712420 | 50000000 | 
libcxx/test/std/utilities/charconv/charconv.to.chars/integral.pass.cpp |
| 0.5 | 50000000 | 100000000 | 
libcxx/test/std/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp |
| 1 | 200000000 | 200000000 | 
libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort_comp.pass.cpp
 |
| 1 | 200000000 | 200000000 | 
libcxx/test/std/algorithms/alg.sorting/alg.sort/stable.sort/stable_sort.pass.cpp
 |

&lt;/details&gt;

So, assuming `0.25` as a conversion factor, this would require increasing the 
limit to at least 8'388'608 to match gcc's default of 33'554'432. 

With heavy metaprogramming features like reflection still on track for C++26, I 
believe it is reasonable to increase this limit. For instance, recursively 
walking all namespaces and performing a set of checks for every reflected 
member of that namespace immediately hits this limit for the global namespace - 
which roughly yields 3000 member reflections even without descending.


This patch increases the default limit to 20'000'000. With this default all but 
the last 3 tests in the first table would not have to override the default. 

I think this is a more reasonable default - on my machine 20 million steps take 
roughly 10 seconds.

---
Full diff: https://github.com/llvm/llvm-project/pull/143785.diff


3 Files Affected:

- (modified) clang/docs/UsersManual.rst (+1-1) 
- (modified) clang/include/clang/Basic/LangOptions.def (+1-1) 
- (modified) clang/include/clang/Driver/Options.td (+1-1) 


``````````diff
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 62844f7e6a2fa..c948ba218c219 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -3992,7 +3992,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 20000000.
 
 .. option:: -ftemplate-depth=N
 
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 789761c1f3647..ba3c8dac8b35d 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -415,7 +415,7 @@ BENIGN_LANGOPT(InstantiationDepth, 32, 1024,
                "maximum template instantiation depth")
 BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
                "maximum constexpr call depth")
-BENIGN_LANGOPT(ConstexprStepLimit, 32, 1048576,
+BENIGN_LANGOPT(ConstexprStepLimit, 32, 20000000,
                "maximum constexpr evaluation steps")
 BENIGN_LANGOPT(EnableNewConstInterp, 1, 0,
                "enable the experimental new constant interpreter")
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 152df89118a6a..4886e7b0a45e0 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2002,7 +2002,7 @@ def fconstexpr_depth_EQ : Joined<["-"], 
"fconstexpr-depth=">, Group<f_Group>,
 def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"Set the maximum number of steps in constexpr function evaluation">,
-  MarshallingInfoInt<LangOpts<"ConstexprStepLimit">, "1048576">;
+  MarshallingInfoInt<LangOpts<"ConstexprStepLimit">, "20000000">;
 def fexperimental_new_constant_interpreter : Flag<["-"], 
"fexperimental-new-constant-interpreter">, Group<f_Group>,
   HelpText<"Enable the experimental new constant interpreter">,
   Visibility<[ClangOption, CC1Option]>,

``````````

</details>


https://github.com/llvm/llvm-project/pull/143785
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to