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

--- Comment #14 from Martin Liška <marxin at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #13)
> So you can loses the TREE_ADDRESSABLE restriction somewhat in requiring at
> most one decl to be TREE_ADDRESSABLE - that's the one you need to keep, the
> others may become aliases.  Given TREE_ADDRESSABLE isn't reliable for
> !TREE_STATIC vars
> we can't merge any exported decls that way.  Consider
> 
> const int foo1;
> const int foo2;
> 
> int *bar();  // in other TU, returns address of foo1
> 
> int main ()
> {
>   if (bar() != &foo2)
>     ...;
> }
> 
> not sure if we want to do hand-waving saying that we can't possibly have
> points-to sets mentioning those without seeing the function IL.  Well,
> might be similarly hand-waving as the reference aliasing issue.
> 
> So we could drop the TREE_STATIC restriction if TREE_ADDRESSABLE is reliable
> within the current TU.

Note that this issue happens only with -fmerge-all-constants. And we have
caveat
in documentation that using the option, pointer comparison can be broken:

Languages like C or C++ require each variable,
           including multiple instances of the same variable in recursive
calls, to have distinct locations, so using this option results in
non-conforming behavior.

Thus:

$ cat test.c
const int foo1 = 3;
const int foo2 = 3;

const int *
__attribute__((noinline))
bar()
{
  return &foo1;
}

int main ()
{
  if ((bar() - &foo2) == 0)
    __builtin_abort ();

  return 0;
}

$ gcc test.c -O2 -fno-ipa-icf -fmerge-all-constants  && ./a.out 
Aborted (core dumped)

That said, would be Richi your comment in c#12 a sufficient fix?

Reply via email to