This is a crash on invalid which started when we changed decl_maybe_constant_var_p to say true for references. Then in tsubst_copy we take this branch: if (decl_maybe_constant_var_p (r)) { /* We can't call cp_finish_decl, so handle the initializer by hand. */ tree init = tsubst_init (DECL_INITIAL (t), r, args, complain, in_decl); but tsubst_init can return NULL_TREE, which potential_constant_expression knows how to handle, but reduced_constant_expression_p didn't. So the following patch will fix the ICE.
Bootstrapped/regtested on x86_64-linux, ok for trunk? 2018-04-12 Marek Polacek <pola...@redhat.com> PR c++/85258 * constexpr.c (reduced_constant_expression_p): Return false for null trees. * g++.dg/parse/error61.C: New test. diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c index 75f56df4465..82f14baaefd 100644 --- gcc/cp/constexpr.c +++ gcc/cp/constexpr.c @@ -1773,6 +1773,9 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, bool reduced_constant_expression_p (tree t) { + if (t == NULL_TREE) + return false; + switch (TREE_CODE (t)) { case PTRMEM_CST: @@ -1794,9 +1797,8 @@ reduced_constant_expression_p (tree t) field = NULL_TREE; FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, idx, val) { - if (!val) - /* We're in the middle of initializing this element. */ - return false; + /* If VAL is null, we're in the middle of initializing this + element. */ if (!reduced_constant_expression_p (val)) return false; if (field) diff --git gcc/testsuite/g++.dg/parse/error61.C gcc/testsuite/g++.dg/parse/error61.C index e69de29bb2d..199e1aa721c 100644 --- gcc/testsuite/g++.dg/parse/error61.C +++ gcc/testsuite/g++.dg/parse/error61.C @@ -0,0 +1,14 @@ +// PR c++/85258 +// { dg-do compile { target c++11 } } + +template<int> void foo() +{ + int x[8]; + for (int& i, j : x) // { dg-error "multiple" } + i = 0; // { dg-error "local variable" } +} + +void bar() +{ + foo<0>(); +} Marek