From: Richard Smith Date: Wed, 30 Sep 2020 17:48:00 +0000 (-0700) Subject: Fix interaction of `constinit` and `weak`. X-Git-Tag: llvmorg-13-init~10485 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=892df30a7f344b6cb9995710efbc94bb25cfb95b;p=platform%2Fupstream%2Fllvm.git Fix interaction of `constinit` and `weak`. We previously took a shortcut and said that weak variables never have constant initializers (because those initializers are never correct to use outside the variable). We now say that weak variables can have constant initializers, but are never usable in constant expressions. --- diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index c96450b..a6c7f30 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2287,6 +2287,10 @@ bool VarDecl::mightBeUsableInConstantExpressions(ASTContext &C) const { if (isa(this)) return false; + // The values of weak variables are never usable in constant expressions. + if (isWeak()) + return false; + // In C++11, any variable of reference type can be used in a constant // expression if it is initialized by a constant expression. if (Lang.CPlusPlus11 && getType()->isReferenceType()) @@ -2414,10 +2418,6 @@ bool VarDecl::isInitICE() const { } bool VarDecl::checkInitIsICE() const { - // Initializers of weak variables are never ICEs. - if (isWeak()) - return false; - EvaluatedStmt *Eval = ensureEvaluatedStmt(); if (Eval->CheckedICE) // We have already checked whether this subexpression is an diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 3bc649b..b17eed2 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -14816,7 +14816,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { const VarDecl *VD; // Look for a declaration of this variable that has an initializer, and // check whether it is an ICE. - if (Dcl->getAnyInitializer(VD) && VD->checkInitIsICE()) + if (Dcl->getAnyInitializer(VD) && !VD->isWeak() && VD->checkInitIsICE()) return NoDiag(); else return ICEDiag(IK_NotICE, cast(E)->getLocation()); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 2d2b805..1275fc0 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -11112,7 +11112,7 @@ QualType Sema::CheckComparisonCategoryType(ComparisonCategoryType Kind, // might be foobar, including it failing to be a constant expression. // TODO Handle more ways the lookup or result can be invalid. if (!VD->isStaticDataMember() || !VD->isConstexpr() || !VD->hasInit() || - !VD->checkInitIsICE()) + VD->isWeak() || !VD->checkInitIsICE()) return UnsupportedSTLError(USS_InvalidMember, MemName, VD); // Attempt to evaluate the var decl as a constant expression and extract diff --git a/clang/test/SemaCXX/cxx20-constinit.cpp b/clang/test/SemaCXX/cxx20-constinit.cpp new file mode 100644 index 0000000..a572b91 --- /dev/null +++ b/clang/test/SemaCXX/cxx20-constinit.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -std=c++20 -verify +// expected-no-diagnostics + +constinit int a __attribute__((weak)) = 0;