]> granicus.if.org Git - clang/commitdiff
[CodeGen] Indirect fields can initialize a union
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 30 May 2015 09:12:07 +0000 (09:12 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 30 May 2015 09:12:07 +0000 (09:12 +0000)
The first named data member is the field used to default initialize the
union.  An IndirectFieldDecl can introduce the first named data member
of a union.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@238649 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGRecordLayoutBuilder.cpp
test/CodeGenCXX/pointers-to-data-members.cpp

index 73ca0cc1c3d5e2cc4383ebd3b4acef8f34377c45..b90b3ab61d8e59b3cb4263ae66fd40cfdaa58a50 100644 (file)
@@ -1349,8 +1349,14 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM,
     }
 
     // For unions, stop after the first named field.
-    if (record->isUnion() && Field->getDeclName())
-      break;
+    if (record->isUnion()) {
+      if (Field->getIdentifier())
+        break;
+      if (const auto *FieldRD =
+              dyn_cast_or_null<RecordDecl>(Field->getType()->getAsTagDecl()))
+        if (FieldRD->findFirstNamedDataMember())
+          break;
+    }
   }
 
   // Fill in the virtual bases, if we're working with the complete object.
index 72ecd65c28a9622394823604e6cdec161f3c20e0..c89d5cc3892a1d6e7ccd53fe89db91ccd9ee2d95 100644 (file)
@@ -314,9 +314,13 @@ void CGRecordLowering::lowerUnion() {
     // If this is the case, then we aught not to try and come up with a "better"
     // type, it might not be very easy to come up with a Constant which
     // correctly initializes it.
-    if (!SeenNamedMember && Field->getDeclName()) {
-      SeenNamedMember = true;
-      if (!isZeroInitializable(Field)) {
+    if (!SeenNamedMember) {
+      SeenNamedMember = Field->getIdentifier();
+      if (!SeenNamedMember)
+        if (const auto *FieldRD =
+                dyn_cast_or_null<RecordDecl>(Field->getType()->getAsTagDecl()))
+        SeenNamedMember = FieldRD->findFirstNamedDataMember();
+      if (SeenNamedMember && !isZeroInitializable(Field)) {
         IsZeroInitializable = IsZeroInitializableAsBase = false;
         StorageType = FieldType;
       }
index 0f2ddaac23b176fb36440df0aab3cb91b64a4d35..94337d98a1956bb82555de64febebe82a4195c59 100644 (file)
@@ -285,4 +285,14 @@ S s;
 // CHECK-GLOBAL: @_ZN19FlexibleArrayMember1sE = global %"struct.FlexibleArrayMember::S" zeroinitializer, align 8
 }
 
+namespace IndirectPDM {
+union U {
+  union {
+    int U::*m;
+  };
+};
+U u;
+// CHECK-GLOBAL: @_ZN11IndirectPDM1uE = global %"union.IndirectPDM::U" { %union.anon { i64 -1 } }, align 8
+}
+
 // CHECK-O3: attributes [[NUW]] = { nounwind readnone{{.*}} }