[PATCH] D124038: [clang] Prevent folding of non-const compound expr

serge via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 19 13:26:00 PDT 2022


serge-sans-paille created this revision.
serge-sans-paille added a reviewer: aaron.ballman.
Herald added a project: All.
serge-sans-paille requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

When a non-const compound statement is used to initialize a constexpr pointer,
the pointed value is not const itself and cannot be folded at codegen time.

Fix issue #39324.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D124038

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/SemaCXX/constant-expression-cxx11.cpp


Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===================================================================
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1595,10 +1595,13 @@
 namespace CompoundLiteral {
   // Matching GCC, file-scope array compound literals initialized by constants
   // are lifetime-extended.
-  constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}}
+  constexpr int *p = (int*)(const int[1]){3}; // expected-warning {{C99}}
   static_assert(*p == 3, "");
   static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}}
 
+  constexpr int *q = (int *)(int[1]){3}; // expected-warning {{C99}}
+  static_assert(*q == 3, "");            // expected-error {{constant expression}}
+
   // Other kinds are not.
   struct X { int a[2]; };
   constexpr int *n = (X){1, 2}.a; // expected-warning {{C99}} expected-warning {{temporary}}
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -4289,6 +4289,17 @@
     }
   }
 
+  if (const VarDecl *VD = dyn_cast_or_null<const VarDecl>(
+          LVal.Base.dyn_cast<const ValueDecl *>())) {
+    if (const CompoundLiteralExpr *CLE = dyn_cast_or_null<CompoundLiteralExpr>(
+            VD->getAnyInitializer()->IgnoreCasts())) {
+      QualType CLET = CLE->getType().getCanonicalType();
+      if (!CLET.isConstant(Info.Ctx)) {
+        Info.FFDiag(Conv);
+      }
+    }
+  }
+
   CompleteObject Obj = findCompleteObject(Info, Conv, AK, LVal, Type);
   return Obj && extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124038.423721.patch
Type: text/x-patch
Size: 1716 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220419/a7703d0c/attachment.bin>


More information about the cfe-commits mailing list