aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-11-16 17:42:24 -0500
committerJason Merrill <jason@gcc.gnu.org>2016-11-16 17:42:24 -0500
commit46b2baa723df876837763f269717413d04a226e0 (patch)
treef3a4b93a42b0d4a6d52610ed1b0c016684d17afc
parent2ec15cba58bfe91bf91c536f5360c05a5b12794a (diff)
downloadgcc-46b2baa723df876837763f269717413d04a226e0.zip
gcc-46b2baa723df876837763f269717413d04a226e0.tar.gz
gcc-46b2baa723df876837763f269717413d04a226e0.tar.bz2
PR c++/78373 - ICE with TREE_CONSTANT reference
* decl.c (cp_finish_decl): Don't set TREE_CONSTANT on a reference. * typeck2.c (store_init_value): Likewise. From-SVN: r242523
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/decl.c4
-rw-r--r--gcc/cp/typeck2.c4
-rw-r--r--gcc/testsuite/g++.dg/opt/pr78373.C22
4 files changed, 32 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index fdbd153..088a63c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index c54a2de..2dc9314 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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;
}
}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 022a478..2ca4bf2 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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
index 0000000..9ceef1c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr78373.C
@@ -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>;