[llvm-bugs] [Bug 41367] New: LLVM's ManagedStatic.h fails with VS 2019 <atomic> and clang-cl due to init-order-fiasco and constexpr confusion
via llvm-bugs
llvm-bugs at lists.llvm.org
Wed Apr 3 16:27:04 PDT 2019
https://bugs.llvm.org/show_bug.cgi?id=41367
Bug ID: 41367
Summary: LLVM's ManagedStatic.h fails with VS 2019 <atomic> and
clang-cl due to init-order-fiasco and constexpr
confusion
Product: clang
Version: unspecified
Hardware: PC
OS: Windows NT
Status: NEW
Severity: enhancement
Priority: P
Component: C++
Assignee: unassignedclangbugs at nondot.org
Reporter: rnk at google.com
CC: billy.oneal at gmail.com, blitzrakete at gmail.com,
dgregor at apple.com, erik.pilkington at gmail.com,
llvm-bugs at lists.llvm.org, richard-llvm at metafoo.co.uk,
sfinae at hotmail.com
I installed VS 2019 and tried to self-host clang with the new headers, but it
didn't work. The symptom was this:
[1 processes, 17/531 @ 3.4/s : 4.984s ] Building AttributesCompatFunc.inc...
FAILED: lib/IR/AttributesCompatFunc.inc
cmd.exe /C "cd /D C:\src\llvm-project\build &&
C:\src\llvm-project\build\bin\llvm-tblgen.exe -gen-attrs -I
C:/src/llvm-project/llvm/lib/IR -I C:/src/llvm-project/llvm/include
C:/src/llvm-project/llvm/lib/IR/AttributesCompatFunc.td -o
lib/IR/AttributesCompatFunc.inc -d lib/IR/AttributesCompatFunc.inc.d"
llvm-tblgen.exe: Unknown command line argument '-gen-attrs'. Try:
'C:\src\llvm-project\build\bin\llvm-tblgen.exe -help'
llvm-tblgen.exe: Did you mean '-stats'?
ninja: build stopped: subcommand failed.
The issue here is that command line options aren't being registered. This is
because TopLevelSubCommand is a ManagedStatic<SubCommand>. What happens is that
the cl::opt initializers run first, then ManagedStatic is incorrectly *not*
linker initialized, we run the ManagedStatic ctor, and we zero out the pointer
to the previously constructed list of command line flags.
The issue is that ManagedStaticBase wants to be linker initialized, but the way
it achieves that is by not having a constructor at all. It has members that
look like this:
class ManagedStaticBase {
protected:
// This should only be used as a static variable, which guarantees that this
// will be zero initialized.
mutable std::atomic<void *> Ptr;
mutable void (*DeleterFn)(void*);
mutable const ManagedStaticBase *Next;
With clang-cl, for some reason the default constructor for this class isn't
considered to be constexpr. When I try to explicitly make it constexpr, clang
complains:
C:\src\llvm-project\llvm\include\llvm/Support/ManagedStatic.h(47,3): error:
defaulted definition of default constructor is not constexpr
constexpr ManagedStaticBase() = default;
^
1 error generated.
So, clang thinks the defaulted one won't be constexpr, but it doesn't say why.
Even if it's correct, it should probably point the user at the uninitialized
members. If I initialize the members explicitly like this:
mutable std::atomic<void *> Ptr{nullptr};
mutable void (*DeleterFn)(void*) = nullptr;
mutable const ManagedStaticBase *Next = nullptr;
Then the defaulted default ctor becomes constexpr and everything works as
expected.
The atomic headers have some interesting ifdefs that seem to allude to this
issue:
struct _Atomic_base : _Atomic_impl<_Bytes> {
...
#ifdef __clang__ // TRANSITION, VSO#406237
constexpr _Atomic_base()
_NOEXCEPT_COND(is_nothrow_default_constructible_v<_Ty>) : _My_val() {}
#else // ^^^ no workaround ^^^ // vvv workaround vvv
_Atomic_base() = default;
#endif // VSO#406237
The odd thing is that if this constexpr default ctor didn't exist, we might be
in business? Hard to say.
Another way of looking at this bug, if it's a clang bug, is, why is the
following an error?
struct atomic_ptr {
constexpr atomic_ptr() = default;
void *Ptr = nullptr;
};
struct Foo {
atomic_ptr Ptr;
int y;
constexpr Foo() = default; // why an error?
};
extern Foo obj;
Foo obj;
Just because 'y' has no initializer, Foo can't be constexpr, even if I ask for
it to be?
In the end, I *think* this is a clang bug, but it might be an STL bug, so I
added Billy and STL.
Anyway, there's an obvious workaround, which is to add a real constexpr
constructor to ManagedStatic, assuming that works with all the toolchains we
support. I'm going to try that.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190403/ebe14fa6/attachment.html>
More information about the llvm-bugs
mailing list