[PATCH] D76096: [clang] allow const structs to be constant expressions in initializer lists
Nick Desaulniers via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 12 14:07:10 PDT 2020
nickdesaulniers updated this revision to Diff 250046.
nickdesaulniers added a comment.
- add 2 missing CHECKs
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D76096/new/
https://reviews.llvm.org/D76096
Files:
clang/lib/AST/Expr.cpp
clang/lib/CodeGen/CGExprConstant.cpp
clang/test/CodeGen/const-init.c
clang/test/Sema/init.c
Index: clang/test/Sema/init.c
===================================================================
--- clang/test/Sema/init.c
+++ clang/test/Sema/init.c
@@ -160,3 +160,22 @@
typedef struct { uintptr_t x : 2; } StructWithBitfield;
StructWithBitfield bitfieldvar = { (uintptr_t)&bitfieldvar }; // expected-error {{initializer element is not a compile-time constant}}
+
+// PR45157
+struct PR4517_foo {};
+struct PR4517_bar {
+ struct PR4517_foo foo;
+};
+const struct PR4517_foo my_foo = {};
+struct PR4517_bar my_bar = {
+ .foo = my_foo, // no-warning
+};
+struct PR4517_bar my_bar2 = (struct PR4517_bar){
+ .foo = my_foo, // no-warning
+};
+struct PR4517_bar my_bar3 = {
+ my_foo, // no-warning
+};
+struct PR4517_bar my_bar4 = (struct PR4517_bar){
+ my_foo // no-warning
+};
Index: clang/test/CodeGen/const-init.c
===================================================================
--- clang/test/CodeGen/const-init.c
+++ clang/test/CodeGen/const-init.c
@@ -181,3 +181,20 @@
#pragma pack()
// CHECK: @g31.a = internal global %struct.anon.2 { i16 23122, i32 -12312731, i16 -312 }, align 4
}
+
+struct PR4517_foo {
+ int x;
+};
+struct PR4517_bar {
+ struct PR4517_foo foo;
+};
+const struct PR4517_foo my_foo = {.x = 42};
+struct PR4517_bar my_bar = {.foo = my_foo};
+struct PR4517_bar my_bar2 = (struct PR4517_bar){.foo = my_foo};
+struct PR4517_bar my_bar3 = {my_foo};
+struct PR4517_bar my_bar4 = (struct PR4517_bar){my_foo};
+// CHECK: @my_foo = constant %struct.PR4517_foo { i32 42 }, align 4
+// CHECK: @my_bar = global %struct.PR4517_bar { %struct.PR4517_foo { i32 42 } }, align 4
+// CHECK: @my_bar2 = global %struct.PR4517_bar { %struct.PR4517_foo { i32 42 } }, align 4
+// CHECK: @my_bar3 = global %struct.PR4517_bar { %struct.PR4517_foo { i32 42 } }, align 4
+// CHECK: @my_bar4 = global %struct.PR4517_bar { %struct.PR4517_foo { i32 42 } }, align 4
Index: clang/lib/CodeGen/CGExprConstant.cpp
===================================================================
--- clang/lib/CodeGen/CGExprConstant.cpp
+++ clang/lib/CodeGen/CGExprConstant.cpp
@@ -1007,6 +1007,13 @@
return Visit(PE->getSubExpr(), T);
}
+ llvm::Constant *VisitDeclRefExpr(DeclRefExpr *DRE, QualType T) {
+ if (VarDecl *V = dyn_cast<VarDecl>(DRE->getDecl()))
+ if (V->hasInit())
+ return Visit(V->getInit(), V->getType());
+ return nullptr;
+ }
+
llvm::Constant *
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE,
QualType T) {
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -3158,6 +3158,13 @@
switch (getStmtClass()) {
default: break;
+ case DeclRefExprClass:
+ if (!Ctx.getLangOpts().CPlusPlus && Ctx.getLangOpts().GNUMode) {
+ const QualType &QT = cast<DeclRefExpr>(this)->getDecl()->getType();
+ if (QT->isStructureType() && QT.isConstQualified())
+ return true;
+ }
+ break;
case StringLiteralClass:
case ObjCEncodeExprClass:
return true;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D76096.250046.patch
Type: text/x-patch
Size: 3090 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200312/7d544ec6/attachment-0001.bin>
More information about the cfe-commits
mailing list