PR c++/78373 - ICE with TREE_CONSTANT reference
authorJason Merrill <jason@redhat.com>
Wed, 16 Nov 2016 22:42:24 +0000 (17:42 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 16 Nov 2016 22:42:24 +0000 (17:42 -0500)
* decl.c (cp_finish_decl): Don't set TREE_CONSTANT on a reference.
* typeck2.c (store_init_value): Likewise.

From-SVN: r242523

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/opt/pr78373.C [new file with mode: 0644]

index fdbd153..088a63c 100644 (file)
@@ -1,5 +1,9 @@
 2016-11-16  Jason Merrill  <jason@redhat.com>
 
+       PR c++/78373
+       * decl.c (cp_finish_decl): Don't set TREE_CONSTANT on a reference.
+       * typeck2.c (store_init_value): Likewise.
+
        * decl.c (store_decomp_type, lookup_decomp_type): New.
        (cp_finish_decomp): Call store_decomp_type.
        * semantics.c (finish_decltype_type): Call lookup_decomp_type.
index c54a2de..2dc9314 100644 (file)
@@ -6839,7 +6839,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
          /* Set these flags now for templates.  We'll update the flags in
             store_init_value for instantiations.  */
          DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
-         if (decl_maybe_constant_var_p (decl))
+         if (decl_maybe_constant_var_p (decl)
+             /* FIXME setting TREE_CONSTANT on refs breaks the back end.  */
+             && TREE_CODE (type) != REFERENCE_TYPE)
            TREE_CONSTANT (decl) = 1;
        }
     }
index 022a478..2ca4bf2 100644 (file)
@@ -824,7 +824,9 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
       const_init = (reduced_constant_expression_p (value)
                    || error_operand_p (value));
       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = const_init;
-      TREE_CONSTANT (decl) = const_init && decl_maybe_constant_var_p (decl);
+      /* FIXME setting TREE_CONSTANT on refs breaks the back end.  */
+      if (TREE_CODE (type) != REFERENCE_TYPE)
+       TREE_CONSTANT (decl) = const_init && decl_maybe_constant_var_p (decl);
     }
   value = cp_fully_fold (value);
 
diff --git a/gcc/testsuite/g++.dg/opt/pr78373.C b/gcc/testsuite/g++.dg/opt/pr78373.C
new file mode 100644 (file)
index 0000000..9ceef1c
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/78373
+// { dg-do compile { target c++11 } }
+
+struct A {
+  static A singleton;
+};
+struct B {
+  void m_fn2();
+  virtual int m_fn1();
+};
+struct D : B {
+  static int m_fn3(int, int, int, A) {
+    D &self = singleton;
+    self.m_fn2();
+  }
+  static D singleton;
+};
+template <typename, typename> struct C { bool m_fn4() const; };
+template <typename Base, typename Traits> bool C<Base, Traits>::m_fn4() const {
+  Traits::m_fn3(0, 0, 0, Base::singleton);
+}
+template struct C<A, D>;