I have questions about LTO respecting -target values. Here’s my reproducer code (tested using LLVM 13):
// a.h
#pragma once
struct A {
A();
int a;
};
// a.cc
#include "a.h"
int foo();
A::A() {
a = foo();
}
A a;
// b.cc
#include "a.h"
extern A a;
int bar() {
return a.a;
}
This is unexpected to me, but is it actually an expected outcome?
Is there a way to control LTO’s above section behavior via a flag or linker script?
Alternatively, is there a way to force a .ctors-style ordering of .init_array? I believe this would allow migration from .ctors to .init_array while negating the observable difference between them (yes, I’m somewhat nervous about exposing a latent static init fiasco).
Not honouring the target triple of the input bitcode sounds like a bug. Probably the version is being discarded and set to the default rather than the max of all inputs.
You used a discouraged way to perform the link (invoking the linker directly). If you invoke Clang Driver for the link action, --target=x86_64-unknown-freebsd9 will tell the backend to use .ctors.
@MaskRay When you get the chance, could you take a look at my previous post (build2.sh)? I’m still not sure if there is a bug here or I misunderstood your suggestion.
(And thank you for the blog post you wrote. I found it when looking into this issue and it was incredibly helpful getting me this far.)
Clang 13 is too old and I don’t know whether it works as intended. I checked latest Clang built from source few days ago and it works as intended. The .ctors/.init_array decision is for the whole module and we rely on Clang Driver to set the value based on the target triple. Nowadays Clang supported ELF OSes that don’t use .ctors are all legacy versions (all end-of-life?), it it not necessary to add more support for them.