Hi! COMPOUND_LITERAL_EXPRs are removed from static initializers in record_references_in_initializer, unfortunately decode_addr_const can be called from const_hash_1 from output_constant_def before that happens and as record_references_in_initializer needs a varpool node, we can't call it during the hashing used to check if we have such a constant already.
The following patch handles COMPOUND_LITERAL_EXPRs like they will be handled later on for the purpose of hashing them. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2018-10-19 Jakub Jelinek <ja...@redhat.com> PR middle-end/87647 * varasm.c (decode_addr_const): Handle COMPOUND_LITERAL_EXPR. * gcc.c-torture/compile/pr87647.c: New test. --- gcc/varasm.c.jj 2018-10-11 09:05:48.124511816 +0200 +++ gcc/varasm.c 2018-10-19 13:27:41.921160889 +0200 @@ -2953,6 +2953,11 @@ decode_addr_const (tree exp, struct addr gen_rtx_SYMBOL_REF (Pmode, "origin of addresses")); break; + case COMPOUND_LITERAL_EXPR: + gcc_assert (COMPOUND_LITERAL_EXPR_DECL (target)); + x = DECL_RTL (COMPOUND_LITERAL_EXPR_DECL (target)); + break; + default: gcc_unreachable (); } --- gcc/testsuite/gcc.c-torture/compile/pr87647.c.jj 2018-10-19 13:30:28.797388068 +0200 +++ gcc/testsuite/gcc.c-torture/compile/pr87647.c 2018-10-19 13:30:00.778853626 +0200 @@ -0,0 +1,15 @@ +/* PR middle-end/87647 */ + +struct A {}; +struct A *const b = &(struct A) {}; +struct B { char *s; struct A *t; }; +void bar (struct B *); + +void +foo (void) +{ + struct B a[] = { "", b, "", b, "", b, "", b, "", b, "", b, "", b, "", b, + "", b, "", b, "", b, "", b, "", b, "", b, "", b, "", b, + "", b }; + bar (a); +} Jakub