]> granicus.if.org Git - clang/commitdiff
[CodeGen] Handle flexible array members containing pointers to members
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 26 May 2015 21:28:50 +0000 (21:28 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 26 May 2015 21:28:50 +0000 (21:28 +0000)
Types can be classified as being zero-initializable or
non-zero-initializable.  We used to classify array types by giving them
the classification of their base element type.  However, incomplete
array types are never initialized directly and thus are always
zero-initializable.

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

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

index f94213ac940394fcdcc007af57d91a71f657c684..73ca0cc1c3d5e2cc4383ebd3b4acef8f34377c45 100644 (file)
@@ -1408,10 +1408,6 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
 
     llvm::Constant *Element = EmitNullConstant(ElementTy);
     unsigned NumElements = CAT->getSize().getZExtValue();
-    
-    if (Element->isNullValue())
-      return llvm::ConstantAggregateZero::get(ATy);
-    
     SmallVector<llvm::Constant *, 8> Array(NumElements, Element);
     return llvm::ConstantArray::get(ATy, Array);
   }
index cebe38877ac41e170d016197840f211f79171252..72ecd65c28a9622394823604e6cdec161f3c20e0 100644 (file)
@@ -153,15 +153,10 @@ struct CGRecordLowering {
     return CharUnits::fromQuantity(DataLayout.getABITypeAlignment(Type));
   }
   bool isZeroInitializable(const FieldDecl *FD) {
-    const Type *Type = FD->getType()->getBaseElementTypeUnsafe();
-    if (const MemberPointerType *MPT = Type->getAs<MemberPointerType>())
-      return Types.getCXXABI().isZeroInitializable(MPT);
-    if (const RecordType *RT = Type->getAs<RecordType>())
-      return isZeroInitializable(RT->getDecl());
-    return true;
+    return Types.isZeroInitializable(FD->getType());
   }
   bool isZeroInitializable(const RecordDecl *RD) {
-    return Types.getCGRecordLayout(RD).isZeroInitializable();
+    return Types.isZeroInitializable(RD);
   }
   void appendPaddingBytes(CharUnits Size) {
     if (!Size.isZero())
index 67a9fbec26907397a704175c7e85147786af30f0..e0f926cabd71ee43fbf841f536d78d9f7cb67357 100644 (file)
@@ -715,9 +715,16 @@ bool CodeGenTypes::isZeroInitializable(QualType T) {
   // No need to check for member pointers when not compiling C++.
   if (!Context.getLangOpts().CPlusPlus)
     return true;
-  
-  T = Context.getBaseElementType(T);
-  
+
+  if (const auto *AT = Context.getAsArrayType(T)) {
+    if (isa<IncompleteArrayType>(AT))
+      return true;
+    if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
+      if (Context.getConstantArrayElementCount(CAT) == 0)
+        return true;
+    T = Context.getBaseElementType(T);
+  }
+
   // Records are non-zero-initializable if they contain any
   // non-zero-initializable subobjects.
   if (const RecordType *RT = T->getAs<RecordType>()) {
@@ -733,6 +740,6 @@ bool CodeGenTypes::isZeroInitializable(QualType T) {
   return true;
 }
 
-bool CodeGenTypes::isZeroInitializable(const CXXRecordDecl *RD) {
+bool CodeGenTypes::isZeroInitializable(const RecordDecl *RD) {
   return getCGRecordLayout(RD).isZeroInitializable();
 }
index ef2d987136817483e8614998209fe7ae893a4750..1580e21d11dc72937306025a459af734ebf1d93b 100644 (file)
@@ -308,7 +308,7 @@ public:  // These are internal details of CGT that shouldn't be used externally.
 
   /// IsZeroInitializable - Return whether a record type can be
   /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
-  bool isZeroInitializable(const CXXRecordDecl *RD);
+  bool isZeroInitializable(const RecordDecl *RD);
   
   bool isRecordLayoutComplete(const Type *Ty) const;
   bool noRecordsBeingLaidOut() const {
index bb1b64e0a73fb1b1a4eb7d05edb988fa7902eaaa..0f2ddaac23b176fb36440df0aab3cb91b64a4d35 100644 (file)
@@ -277,4 +277,12 @@ U u;
 // CHECK-GLOBAL: @_ZN7PR212821uE = global %"union.PR21282::U" { i64 -1, [8 x i8] zeroinitializer }, align 8
 }
 
+namespace FlexibleArrayMember {
+struct S {
+  int S::*x[];
+};
+S s;
+// CHECK-GLOBAL: @_ZN19FlexibleArrayMember1sE = global %"struct.FlexibleArrayMember::S" zeroinitializer, align 8
+}
+
 // CHECK-O3: attributes [[NUW]] = { nounwind readnone{{.*}} }