[clang] 892df30 - Fix interaction of `constinit` and `weak`.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 30 10:50:01 PDT 2020


Author: Richard Smith
Date: 2020-09-30T10:49:50-07:00
New Revision: 892df30a7f344b6cb9995710efbc94bb25cfb95b

URL: https://github.com/llvm/llvm-project/commit/892df30a7f344b6cb9995710efbc94bb25cfb95b
DIFF: https://github.com/llvm/llvm-project/commit/892df30a7f344b6cb9995710efbc94bb25cfb95b.diff

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

Added: 
    clang/test/SemaCXX/cxx20-constinit.cpp

Modified: 
    clang/lib/AST/Decl.cpp
    clang/lib/AST/ExprConstant.cpp
    clang/lib/Sema/SemaDeclCXX.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index c96450b8a377..a6c7f30528eb 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<ParmVarDecl>(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 3bc649b96990..b17eed2dc823 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<DeclRefExpr>(E)->getLocation());

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 2d2b80573a69..1275fc0c95b5 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 000000000000..a572b9128907
--- /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;


        


More information about the cfe-commits mailing list