On Thu, Jan 19, 2023 at 12:13 PM Jakub Jelinek via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > Hi! > > For anonymous union members we create artificial VAR_DECLs which > have DECL_VALUE_EXPR for the actual COMPONENT_REF. That works > just fine inside of functions (including global dynamic constructors), > because during gimplification such VAR_DECLs are gimplified as > their DECL_VALUE_EXPR. This is also done during regimplification. > > But references to these artificial vars in DECL_INITIAL expressions > aren't ever replaced by the DECL_VALUE_EXPRs, so we end up either > with link failures like on the testcase below, or worse ICEs with > LTO. > > The following patch fixes those during cp_fully_fold_init where we > already walk all the trees (!data->genericize means that > function rather than cp_fold_function). > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
I noticed (static) structured bindings has a similar issue but is not fixed by this because this checks to see if it is an anonymous union decl. I filed PR 108474 for that. Thanks, Andrew Pinski > > 2023-01-19 Jakub Jelinek <ja...@redhat.com> > > PR c++/53932 > * cp-gimplify.cc (cp_fold_r): During cp_fully_fold_init replace > DECL_ANON_UNION_VAR_P VAR_DECLs with their corresponding > DECL_VALUE_EXPR. > > * g++.dg/init/pr53932.C: New test. > > --- gcc/cp/cp-gimplify.cc.jj 2023-01-16 11:52:16.065734330 +0100 > +++ gcc/cp/cp-gimplify.cc 2023-01-19 18:13:54.592661735 +0100 > @@ -1010,6 +1010,16 @@ cp_fold_r (tree *stmt_p, int *walk_subtr > } > break; > > + case VAR_DECL: > + /* In initializers replace anon union artificial VAR_DECLs > + with their DECL_VALUE_EXPRs, as nothing will do it later. */ > + if (DECL_ANON_UNION_VAR_P (stmt) && !data->genericize) > + { > + *stmt_p = stmt = unshare_expr (DECL_VALUE_EXPR (stmt)); > + break; > + } > + break; > + > default: > break; > } > --- gcc/testsuite/g++.dg/init/pr53932.C.jj 2023-01-19 18:22:24.837231192 > +0100 > +++ gcc/testsuite/g++.dg/init/pr53932.C 2023-01-19 18:20:51.776586408 +0100 > @@ -0,0 +1,25 @@ > +// PR c++/53932 > +// { dg-do link } > + > +static union { int i; }; > +int &r = i; > +int s = i; > +int *t = &i; > + > +void > +foo (int **p, int *q) > +{ > + static int &u = i; > + static int v = i; > + static int *w = &i; > + int &x = i; > + int y = i; > + int *z = &i; > + *p = &i; > + *q = i; > +} > + > +int > +main () > +{ > +} > > Jakub >