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 <pola...@redhat.com> 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()]; +}