This test segvs since r269078, this hunk in particular:
@@ -4581,8 +4713,9 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx,
tree t,
break;
case SIZEOF_EXPR:
- r = fold_sizeof_expr (t);
- VERIFY_CONSTANT (r);
+ r = cxx_eval_constant_expression (ctx, fold_sizeof_expr (t), lval,
+ non_constant_p, overflow_p,
+ jump_target);
break;
In a template, fold_sizeof_expr will just create a new SIZEOF_EXPR, that is the
same, but not identical; see cxx_sizeof_expr. Then cxx_eval_constant_expression
calls itself on this new expr, then fold_sizeof_expr creates another
SIZEOF_EXPR.
Then we call cxx_eval_constant_expression...
The call to cxx_eval_constant_expression is there to keep constexpr-vla1.C
working. But we can avoid calling it in a template and it'll still work, and
we avoid this nasty recursion.
Bootstrapped/regtested on x86_64-linux, ok for trunk and 9?
2019-06-10 Marek Polacek <[email protected]>
PR c++/90825 - endless recursion when evaluating sizeof.
* constexpr.c (cxx_eval_constant_expression): Don't recurse on the
result of fold_sizeof_expr in a template.
* g++.dg/cpp0x/constexpr-sizeof2.C: New test.
diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index a2f29694462..a68aac3b531 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -4808,9 +4808,13 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx,
tree t,
break;
case SIZEOF_EXPR:
- r = cxx_eval_constant_expression (ctx, fold_sizeof_expr (t), lval,
- non_constant_p, overflow_p,
- jump_target);
+ r = fold_sizeof_expr (t);
+ /* Don't recurse in a template, because then fold_sizeof_expr merely
+ creates a new SIZEOF_EXPR, leading to an infinite recursion. */
+ if (!processing_template_decl)
+ r = cxx_eval_constant_expression (ctx, r, lval,
+ non_constant_p, overflow_p,
+ jump_target);
break;
case COMPOUND_EXPR:
diff --git gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof2.C
gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof2.C
new file mode 100644
index 00000000000..2d3a169d28c
--- /dev/null
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof2.C
@@ -0,0 +1,14 @@
+// PR c++/90825 - endless recursion when evaluating sizeof.
+// { dg-do compile { target c++11 } }
+
+class address {
+ char host_[63];
+public:
+ static constexpr unsigned buffer_size() noexcept { return sizeof(host_); }
+};
+
+template <class Archive>
+void load()
+{
+ char host[address::buffer_size()];
+}