Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LLVM's ManagedStatic.h fails with VS 2019 <atomic> and clang-cl due to init-order-fiasco and constexpr confusion #40712

Closed
rnk opened this issue Apr 3, 2019 · 21 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla c++

Comments

@rnk
Copy link
Collaborator

rnk commented Apr 3, 2019

Bugzilla Link 41367
Resolution FIXED
Resolved on Feb 04, 2021 12:09
Version unspecified
OS Windows NT
Blocks #44654
CC @amaiorano,@BillyONeal,@DougGregor,@ASDenysPetrov,@mvhooren,@RKSimon,@zygoloid,@StephanTLavavej,@tstellar,@yuanfang-chen
Fixed by commit(s) 46e5c5f 28a6713

Extended Description

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

@rnk
Copy link
Collaborator Author

rnk commented Apr 3, 2019

assigned to @rnk

@rnk
Copy link
Collaborator Author

rnk commented Apr 3, 2019

After discussing this further here, we think this is definitely an LLVM bug, not a clang bug or a VC STL bug.

@BillyONeal
Copy link
Contributor

VSO#406237 is "C1XX does not do constant initialization where the standard requires". Basically, the compiler doesn't do constant initialization unless you are declaring an instance of a thing which is itself actually constexpr. This let us implement P0883 for clang but not for c1xx yet.

Billy O'Neal
Visual C++ Libraries

@RKSimon
Copy link
Collaborator

RKSimon commented Apr 4, 2019

Reid - after rL357655 I'm seeing a very similar llvm-tblgen error on VS2017 - I've only been able to repro on msbuild debug builds so far.

@RKSimon
Copy link
Collaborator

RKSimon commented Apr 4, 2019

Reid - after rL357655 I'm seeing a very similar llvm-tblgen error on VS2017

  • I've only been able to repro on msbuild debug builds so far.

Reverted in rL357685

@rnk
Copy link
Collaborator Author

rnk commented Apr 4, 2019

VSO#406237 is "C1XX does not do constant initialization where the standard
requires". Basically, the compiler doesn't do constant initialization unless
you are declaring an instance of a thing which is itself actually constexpr.
This let us implement P0883 for clang but not for c1xx yet.

Billy O'Neal
Visual C++ Libraries

Reid - after rL357655 I'm seeing a very similar llvm-tblgen error on VS2017

  • I've only been able to repro on msbuild debug builds so far.

So, if I understand correctly, my fix, rL357655, ran into exactly the issue that Billy is describing with the Visual C++ compiler from VS 2017. =/ I have yet to find a proper solution.

@rnk
Copy link
Collaborator Author

rnk commented Jul 15, 2019

I relanded a fix back in April in r359135.

@ASDenysPetrov
Copy link
Contributor

There was a bug of constexpr ctor in VS2019 compiler until ver 16.5, that really caused the problem.
It is fixed now. https://developercommunity.visualstudio.com/content/problem/262083/compiler-emits-dynamic-initializer-for-variable-wi.html
I've provided a fix for LLVM https://reviews.llvm.org/D80433.

@RKSimon
Copy link
Collaborator

RKSimon commented May 22, 2020

Reopened to deal with the 16.5+ case

@ASDenysPetrov
Copy link
Contributor

The fix for MSVC v16.5+ loaded.

@RKSimon
Copy link
Collaborator

RKSimon commented May 27, 2020

This affects building the 10.0 release build with VS 16.6:

https://llvm.discourse.group/t/llvm-not-building-in-vusual-studio/1139

I'd like to propose we merge https://reviews.llvm.org/D80433 / rG46e5c5fe778b into the branch.

@ASDenysPetrov
Copy link
Contributor

Simon, I'm reletively a newcomer. Could you please explain how to do that?

@RKSimon
Copy link
Collaborator

RKSimon commented May 27, 2020

Simon, I'm reletively a newcomer. Could you please explain how to do that?

We just need to get a consensus on this ticket that rG46e5c5fe778b should be merged into the 10.X release branch and Tom will handle the actual merge (by blocking [Bug #​45309] he has visibility on merge candidates).

Reid - any comments?

@efriedma-quic
Copy link
Collaborator

*** Bug llvm/llvm-bugzilla-archive#46108 has been marked as a duplicate of this bug. ***

@tstellar
Copy link
Collaborator

Reid, is this OK to backport?

@tstellar
Copy link
Collaborator

This looks safe to me, so I'm going to merge this.

@tstellar
Copy link
Collaborator

Merged: 28a6713

@rnk
Copy link
Collaborator Author

rnk commented Feb 4, 2021

*** Bug llvm/llvm-bugzilla-archive#49027 has been marked as a duplicate of this bug. ***

@tstellar
Copy link
Collaborator

mentioned in issue #44654

@efriedma-quic
Copy link
Collaborator

mentioned in issue llvm/llvm-bugzilla-archive#46108

@amaiorano
Copy link
Contributor

mentioned in issue llvm/llvm-bugzilla-archive#49027

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c++
Projects
None yet
Development

No branches or pull requests

7 participants