From 51d72abe5ea04e7ec778d5fb1f0883be090057b5 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 17 Nov 2014 15:17:56 -0500 Subject: [PATCH] re PR c++/50473 ([C++0x] ICE in type_has_nontrivial_copy_init, at cp/tree.c:2574) PR c++/50473 * decl.c (cp_finish_decl): Don't try to process a non-dependent constant initializer for a reference. * pt.c (value_dependent_expression_p): A reference is always dependent. * call.c (extend_ref_init_temps_1): Also clear TREE_SIDE_EFFECTS on any NOP_EXPRs. From-SVN: r217672 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/call.c | 4 +++- gcc/cp/decl.c | 1 + gcc/cp/pt.c | 2 ++ gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C | 2 +- gcc/testsuite/g++.dg/cpp0x/constexpr-ref5.C | 13 +++++++++++++ 6 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-ref5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 18e06d8..05ca493 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2014-11-17 Jason Merrill + PR c++/50473 + * decl.c (cp_finish_decl): Don't try to process a non-dependent + constant initializer for a reference. + * pt.c (value_dependent_expression_p): A reference is always + dependent. + * call.c (extend_ref_init_temps_1): Also clear TREE_SIDE_EFFECTS + on any NOP_EXPRs. + Handle C++14 constexpr flow control. * constexpr.c (cxx_eval_loop_expr, cxx_eval_switch_expr): New. (cxx_eval_statement_list): New. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4f0b172..06162aa 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -9712,9 +9712,11 @@ extend_ref_init_temps_1 (tree decl, tree init, vec **cleanups) { tree subinit = NULL_TREE; *p = set_up_extended_ref_temp (decl, *p, cleanups, &subinit); + recompute_tree_invariant_for_addr_expr (sub); + if (init != sub) + init = fold_convert (TREE_TYPE (init), sub); if (subinit) init = build2 (COMPOUND_EXPR, TREE_TYPE (init), subinit, init); - recompute_tree_invariant_for_addr_expr (sub); } return init; } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 47da0ca..e69b521 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6419,6 +6419,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, else if (init && init_const_expr_p && !type_dependent_p + && TREE_CODE (type) != REFERENCE_TYPE && decl_maybe_constant_var_p (decl) && !type_dependent_init_p (init) && !value_dependent_init_p (init)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1ee3dc1..c0f3b8c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -20959,6 +20959,8 @@ value_dependent_expression_p (tree expression) if (DECL_INITIAL (expression) && decl_constant_var_p (expression) && (TREE_CODE (DECL_INITIAL (expression)) == TREE_LIST + /* cp_finish_decl doesn't fold reference initializers. */ + || TREE_CODE (TREE_TYPE (expression)) == REFERENCE_TYPE || value_dependent_expression_p (DECL_INITIAL (expression)))) return true; return false; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C index 98f53b1..c548337 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C @@ -3,7 +3,7 @@ struct A { - static constexpr int&& i = 0; // { dg-error "initialization" } + static constexpr int&& i = 0; }; int j = A::i; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ref5.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref5.C new file mode 100644 index 0000000..230510c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref5.C @@ -0,0 +1,13 @@ +// PR c++/50473 +// { dg-do compile { target c++11 } } + +constexpr int f() { return 1; } + +template +struct test +{ + static constexpr const auto& value = f(); + int a[value]; +}; + +test t; -- 2.7.4