llvm / llvm/llvm-project

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

Open
#162,989 7 comments 0 reactions 0 assignees View on GitHub
LTO
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Enabling LTO silently breaks programs like so:

```cpp

// 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

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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.