Hello,
On Thu, 26 Mar 2020, Richard Biener wrote:
> > ===== b.c:
> >
> > __attribute__((weak))
> > __attribute__((noinline))
> >
> > int a()
> > {
> > return 1;
> > }
> >
> > __attribute__((noinline))
> > static int b() __attribute__((alias("a")));
> > void
> > test()
> > {
> > if (b()!=1)
> > __builtin_abort ();
> > }
> >
> > ===== b.c:
> >
> > __attribute__((noinline))
> > int a();
> >
> > int a()
> > {
> > return 2;
> > }
> > extern void test ();
> > int
> > main()
> > {
> > if (a() != 2)
> > __builtin_abort ();
> > test();
> > return 0;
> > }
> >
> > Here LTO linking will replace weak symbol a() by definition from b.c and
> > rediect static alias b in a.c to this definition which is wrong.
>
> Is it? What does a non-weak local alias to a weak function mean?
I think we should continue to try to model ELF semantics re weak and
aliases. If so, then yes, LTO gets it wrong and the above testcase should
not abort. Weak doesn't enter the picture for creating aliases (the
aliases is created with the declaration, and we require an available
definition, and the alias is henceforth bound to _that_ very definition).
I.e. the 'a.c:b' name should continue to refer to the same code snippet
identified by the a.c:a name, not be redirected to the overriding b.c:a.
I'm wondering about the amount of code necessary to fix this. I think
that points towards a wrong level of representation somewhere, and perhaps
_that_ should be changed instead of trying to work around it.
For instance, right now aliases are different from non-aliases, whereas in
reality there's no difference: there are simply names referring to code or
data snippets, and it so happens that for some snippets there are multiple
names, and it further just so happens that some names for a code snippet
become overridden/removed by other names for other code snippets, which
doesn't invalidate the fact that there still is another name for the first
snippet.
If it were modelled like that in cgraph/lto all the rest would naturally
follow. (Of course you would need tracking of when some code/data
snippets can't be referred to by name anymore (and hence are useless),
because all names for them went away, or none of the existing names is
used anymore, but I don't think that materially would change much in our
internal data structures).
Ciao,
Michael.