[cfe-dev] weak_odr constant versus weak_odr global

Richard Smith richard at metafoo.co.uk
Tue Nov 1 17:19:03 PDT 2011


Hi

[Adding cfe-dev to widen the net]

On Tue, November 1, 2011 23:19, Richard Smith wrote:
> We recently narrowed down a clang regression to the following testcase:
>
> struct S { static const int x; };
> template<typename T> struct U { static const int k; };
> template<typename T> const int U<T>::k = T::x;
>
> #ifdef TU1
> extern int f();
> const int S::x = 42;
> int main() { return f() + U<S>::k; }
> #endif
>
> #ifdef TU2
> int f() { return U<S>::k; }
> #endif
>
> /* Steps to repro:
>
> clang repro.cpp -DTU1 -c -o tu1.o
> clang repro.cpp -DTU2 -c -o tu2.o
> clang tu1.o tu2.o
> ./a.out
>
> */
>
> This segfaults, because... in TU1, we get:
>
> @_ZN1UI1SE1kE = weak_odr constant i32 42, align 4
>
> and in TU2, we get:
>
> @_ZN1UI1SE1kE = weak_odr global i32 0, align 4
>
> plus a global constructor which writes to @_ZN1UI1SE1kE. The linker then
> selects the symbol from TU1, which ends up in a read-only section, resulting
> in the binary crashing when TU2 tries to write to it.
>
> Is this a clang bug (should we be generating a weak_odr global, and losing
> optimization opportunities in TU1), or is this an llvm bug (should weak_odr
> constants be banned from read-only sections, since another module might write
> to them)?

I think this is best fixed in llvm, since that gives maximum optimization
opportunities: it's fine to propagate weak_odr constant values, even if some
other module has the same object as a non-constant. Plus, with LTO, we'd want
to merge the weak_odr constant and weak_odr global symbols into a weak_odr
constant (and simultaneously remove any writes into the global).

Thanks,
Richard




More information about the cfe-dev mailing list