]> granicus.if.org Git - clang/commitdiff
For gcc compatibility, size of a class which is zero
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 2 Feb 2011 19:36:18 +0000 (19:36 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 2 Feb 2011 19:36:18 +0000 (19:36 +0000)
but has non-empty data fields, such as array of zero length,
remains zero.
// rdar://8945175

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

lib/AST/RecordLayoutBuilder.cpp
test/CodeGenCXX/non-empty-class-size-zero.cpp [new file with mode: 0644]

index 730ec2135808de60d6a312ab1656f83866195b6a..a871c3d1766a938ed3a1ec3cac2c603e0c2cf71d 100644 (file)
@@ -1469,8 +1469,17 @@ void RecordLayoutBuilder::LayoutField(const FieldDecl *D) {
 
 void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
   // In C++, records cannot be of size 0.
-  if (Context.getLangOptions().CPlusPlus && Size == 0)
-    Size = 8;
+  if (Context.getLangOptions().CPlusPlus && Size == 0) {
+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+      // Compatibility with gcc requires a class (pod or non-pod)
+      // which is not empty but of size 0; such as having fields of
+      // array of zero-length, remains of Size 0
+      if (RD->isEmpty())
+        Size = 8;
+    }
+    else
+      Size = 8;
+  }
   // Finally, round the size of the record up to the alignment of the
   // record itself.
   uint64_t UnpaddedSize = Size - UnfilledBitsInLastByte;
diff --git a/test/CodeGenCXX/non-empty-class-size-zero.cpp b/test/CodeGenCXX/non-empty-class-size-zero.cpp
new file mode 100644 (file)
index 0000000..810717b
--- /dev/null
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// rdar://8945175
+
+struct X { 
+  int array[0]; 
+  int array1[0]; 
+  int array2[0]; 
+  X();
+  ~X();
+};
+
+struct Y {
+  int first;
+  X padding;
+  int second;
+};
+
+int main() {
+// CHECK: store i32 0, i32* [[RETVAL:%.*]]
+  return sizeof(Y) -8 ;
+}