diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 827a177f9bf830..17cf3ccdeb6a94 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -560,13 +560,25 @@ bool CheckGlobalInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { return false; } +static bool CheckWeak(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { + if (!Ptr.isWeak()) + return true; + + const auto *VD = Ptr.getDeclDesc()->asVarDecl(); + assert(VD); + S.FFDiag(S.Current->getLocation(OpPC), diag::note_constexpr_var_init_weak) + << VD; + S.Note(VD->getLocation(), diag::note_declared_at); + + return false; +} + bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK) { if (!CheckLive(S, OpPC, Ptr, AK)) return false; if (!CheckConstant(S, OpPC, Ptr)) return false; - if (!CheckDummy(S, OpPC, Ptr, AK)) return false; if (!CheckExtern(S, OpPC, Ptr)) @@ -579,6 +591,8 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, return false; if (!CheckTemporary(S, OpPC, Ptr, AK)) return false; + if (!CheckWeak(S, OpPC, Ptr)) + return false; if (!CheckMutable(S, OpPC, Ptr)) return false; if (!CheckVolatile(S, OpPC, Ptr, AK)) diff --git a/clang/test/AST/ByteCode/weak.cpp b/clang/test/AST/ByteCode/weak.cpp index 0322241beef83b..52c75229d9ec7a 100644 --- a/clang/test/AST/ByteCode/weak.cpp +++ b/clang/test/AST/ByteCode/weak.cpp @@ -7,3 +7,11 @@ int ha[(bool)&a]; // both-warning {{variable length arrays in C++ are a Clang ex int ha2[&a == nullptr]; // both-warning {{variable length arrays in C++ are a Clang extension}} \ // both-note {{comparison against address of weak declaration '&a' can only be performed at runtime}} \ // both-error {{variable length array declaration not allowed at file scope}} + +extern const int W1 __attribute__((weak)) = 10; // both-note {{declared here}} +static_assert(W1 == 10, ""); // both-error {{static assertion expression is not an integral constant expression}} \ + // both-note {{initializer of weak variable 'W1' is not considered constant because it may be different at runtime}} + +extern const int W2 __attribute__((weak)); // both-note {{declared here}} +static_assert(W2 == 10, ""); // both-error {{static assertion expression is not an integral constant expression}} \ + // both-note {{initializer of 'W2' is unknown}} diff --git a/clang/test/SemaCXX/weak-init.cpp b/clang/test/SemaCXX/weak-init.cpp index a88d32bdca5a17..0147b80f382402 100644 --- a/clang/test/SemaCXX/weak-init.cpp +++ b/clang/test/SemaCXX/weak-init.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only +// RUN: %clang_cc1 %s -verify -fsyntax-only -fexperimental-new-constant-interpreter extern const int W1 __attribute__((weak)) = 10; // expected-note {{declared here}}