llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.34k stars 12.13k forks source link

Static inline variable and global are initialized in incorrect order with optimization on #116950

Open semushin-s opened 1 week ago

semushin-s commented 1 week ago

Please take a look at the following example:

struct A {
    A() {
        a = 1;
    }

    int a;
};

struct B {
    B() : _a(_ca) {}

    A _a;
    static inline A _ca;
};

B b;

int main() {
    return b._a.a;
}

Currently it returns 0 with -O2 using clang: https://gcc.godbolt.org/z/66hGqoaj8 and returns 1 with -O0. Compiled by all the other compilers, it results in 1 as well.

It seems initialization of static inline A _ca should be done earlier than initialization of B. According to [basic.start.dynamic]: if V has partially-ordered initialization, W does not have unordered initialization, and for every definition E of W there exists a definition D of V such that D is appearance-ordered before E ... V is sequenced before the initialization of W;

Let's say static inline A _ca is definition of V, B b is definition of W, seems by appearance order _ca should have been initialized before b, however with optimization a=1 initialization fails to happen before initializing B b apparently. Please correct me if my interpretation of the standard is wrong in this case.

semushin-s commented 2 days ago

Another interesting aspect of this issue, coming from how it was discovered originally. Initialization order may be affected by adding irrelevant global constants to original example. Basically it comes to the following:

Might not be that relevant since it might be just optimization noise, but makes it more surprising when encountering this in the wild.