aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-11-17 15:17:56 -0500
committerJason Merrill <jason@gcc.gnu.org>2014-11-17 15:17:56 -0500
commit51d72abe5ea04e7ec778d5fb1f0883be090057b5 (patch)
tree6ba13b465e2a25a0a17dad66c10d9b9043cdfe4f
parent88436c83a4e5004b8b538cde59c3e9750b0bb8de (diff)
downloadgcc-51d72abe5ea04e7ec778d5fb1f0883be090057b5.zip
gcc-51d72abe5ea04e7ec778d5fb1f0883be090057b5.tar.gz
gcc-51d72abe5ea04e7ec778d5fb1f0883be090057b5.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/call.c4
-rw-r--r--gcc/cp/decl.c1
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ref5.C13
6 files changed, 28 insertions, 2 deletions
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 <jason@redhat.com>
+ 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<tree, va_gc> **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<class T>
+struct test
+{
+ static constexpr const auto& value = f();
+ int a[value];
+};
+
+test<int> t;