Reproducer: // Steps to reproduce: // clang++ -std=c++14 -fsanitize=address -DTU_ONE -shared -fPIC -o libfoo.so test.cpp // clang++ -std=c++1z -fsanitize=address test.cpp libfoo.so // ./a.out // EXPECTED: exit success // ACTUAL: AddressSanitizer: odr-violation struct Foo { static constexpr bool inline_var = true; }; #ifdef TU_ONE constexpr bool Foo::inline_var; #else void test(const bool&) {} int main() { test(Foo::inline_var); } #endif In the above reproducer the main program generates a definition for Foo::inline_var according to the C++17 inline variable rules. The program then links to a library compiled as C++14 which provides the explicit definition for `Foo::inline_bool`. When this program is run ASAN will emit an odr-violation diagnostic for 'inline_bool'. I believe this diagnostic is a false positive even though one of the two definitions was not compiled with C++17 inline variable semantics.
I think the bug is that C++17 introduces an ABI break with C++14 by changing the linkage of inline_var from external to linkonce_odr.
Not as asan bug, the ODR violation is real.
Not _an_ asan bug
(In reply to Reid Kleckner from comment #1) > I think the bug is that C++17 introduces an ABI break with C++14 by changing > the linkage of inline_var from external to linkonce_odr. Is that an ABI break though? If the external definition and linkonce_odr definition are linked together the link will succeed, right? (the linkonce_odr will be dropped in favor of the external definition) (maybe this is fine for ELF/maybe some other object formats but not in LLVM IR? Not sure what the semantics of linking a Module with a linkonce_odr definition with a Module with an external/strong definition are) I mean it's a break if you do it the other way - ship your C++17 library to someone building as C++14. But if you ship your C++14 library to people building with your headers as C++17? That seems like it might thread the needle & be 'good'-ish?