https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119359

            Bug ID: 119359
           Summary: incomplete folding of initializers leads to dynamic
                    initialization
           Product: gcc
           Version: 14.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nathan at gcc dot gnu.org
  Target Milestone: ---

Created attachment 60811
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=60811&action=edit
reproducer

#ifdef BUG
#define ADDR (16 + 16 * 0)
#else
#define ADDR 16
#endif

int *const FOO = (int *)ADDR;
int *const BAR = FOO;

int foo () {return *FOO;}
int bar () {return *addr;}



g++ -O2 results in static initialization (and folding away the const vars)
g++ -O2 -DBUG results in dynamic initialization of 'run' but not 'addr':

_Z4frobv:
        movq    _ZL3run(%rip), %rax
        movl    (%rax), %eax
        ret

_GLOBAL__sub_I__Z4frobv:
        .cfi_startproc
        movq    $16, _ZL3run(%rip)
        ret

What happens is we end up inside initializer_constant_valid_p (varasm.cc)
examining ADDR's initializer when considering RUN's initializer.  We see an
unfolded tree '(+ 16 (* 16 0))' and that multiplication causes us to think it's
not a valid constant.  I think initializer_constant_valid_p is assuming trees
are fully folded?

I suspect we need to store the folded initializer into DECL_INITIAL or
something.

Reply via email to