diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fdbd1536002..088a63cab84 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-11-16 Jason Merrill + 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 c54a2de0af6..2dc9314bc1e 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 022a47883a0..2ca4bf241ec 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -824,7 +824,9 @@ store_init_value (tree decl, tree init, vec** 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 00000000000..9ceef1cc732 --- /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 struct C { bool m_fn4() const; }; +template bool C::m_fn4() const { + Traits::m_fn3(0, 0, 0, Base::singleton); +} +template struct C;