re PR c++/50473 ([C++0x] ICE in type_has_nontrivial_copy_init, at cp/tree.c:2574)
authorJason Merrill <jason@redhat.com>
Mon, 17 Nov 2014 20:17:56 +0000 (15:17 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 17 Nov 2014 20:17:56 +0000 (15:17 -0500)
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
gcc/cp/call.c
gcc/cp/decl.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/constexpr-ice12.C
gcc/testsuite/g++.dg/cpp0x/constexpr-ref5.C [new file with mode: 0644]

index 18e06d8..05ca493 100644 (file)
@@ -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.
index 4f0b172..06162aa 100644 (file)
@@ -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;
 }
index 47da0ca..e69b521 100644 (file)
@@ -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))
index 1ee3dc1..c0f3b8c 100644 (file)
@@ -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;
index 98f53b1..c548337 100644 (file)
@@ -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 (file)
index 0000000..230510c
--- /dev/null
@@ -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;