Skip to content

LTO optimises out conditional code in extern C++ global initialised by mod_init_funcs that's inside mod_init_funcs #162989

@VisualEhrmanntraut

Description

@VisualEhrmanntraut

Enabling LTO silently breaks programs like so:

// A.hpp
extern "C" bool some_external_bool; // comes from dynamic linking

struct A {
    const bool cond;

    A() : cond{some_external_bool} {}
};

extern const A currentA;

// A.cpp

#include "A.hpp"

const A currentA {};

// B.hpp

#include "A.hpp"

struct BConstants {
    unsigned int val;

    B() { this->val = currentA::cond ? 0xDEAD : 0xBEEF; }

    static const BConstants singleton;
};

// B.cpp

#include "B.hpp"

const BConstants BConstants::singleton {};

// main.cpp

#include "B.hpp"
#include <iostream>

int main() {
    std::cout << "val is: " << BConstants::singleton.val << std::endl;
}

Note: Manually typed-out code, may need some adjustments to compile, hopefully not. I was ready to break my keyboard trying to understand why my macOS Kernel Extension was misbehaving, my patience is waning.

Yes, I tried with both Apple Clang and upstream LLVM Clang, it happened with both.

The output will always be 0xBEEF no matter the value of some_external_bool, because LTO is removing the code and replacing it with a constant 0xBEEF.

Metadata

Metadata

Assignees

No one assigned

    Labels

    LTOLink time optimization (regular/full LTO or ThinLTO)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions