[cfe-commits] r121436 - in /cfe/trunk: lib/CodeGen/CGRecordLayoutBuilder.cpp test/CodeGenCXX/pragma-pack.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Thu Dec 9 16:11:00 PST 2010


Author: akirtzidis
Date: Thu Dec  9 18:11:00 2010
New Revision: 121436

URL: http://llvm.org/viewvc/llvm-project?rev=121436&view=rev
Log:
Fix another obscure corner layout case.

Added:
    cfe/trunk/test/CodeGenCXX/pragma-pack.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp

Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=121436&r1=121435&r2=121436&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Thu Dec  9 18:11:00 2010
@@ -125,7 +125,7 @@
                              const ASTRecordLayout &Layout);
 
   /// ComputeNonVirtualBaseType - Compute the non-virtual base field types.
-  void ComputeNonVirtualBaseType(const CXXRecordDecl *RD);
+  bool ComputeNonVirtualBaseType(const CXXRecordDecl *RD);
   
   /// LayoutField - layout a single field. Returns false if the operation failed
   /// because the current struct is not packed.
@@ -612,7 +612,7 @@
   }
 }
 
-void 
+bool
 CGRecordLayoutBuilder::ComputeNonVirtualBaseType(const CXXRecordDecl *RD) {
   const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(RD);
 
@@ -624,26 +624,27 @@
   // First check if we can use the same fields as for the complete class.
   if (AlignedNonVirtualTypeSize == Layout.getSize() / 8) {
     NonVirtualBaseTypeIsSameAsCompleteType = true;
-    return;
+    return true;
   }
 
-  NonVirtualBaseFieldTypes = FieldTypes;
-
   // Check if we need padding.
   uint64_t AlignedNextFieldOffset =
     llvm::RoundUpToAlignment(NextFieldOffsetInBytes, 
                              getAlignmentAsLLVMStruct());
 
-  assert(AlignedNextFieldOffset <= AlignedNonVirtualTypeSize && 
-         "Size mismatch!");
+  if (AlignedNextFieldOffset > AlignedNonVirtualTypeSize)
+    return false; // Needs packing.
+
+  NonVirtualBaseFieldTypes = FieldTypes;
 
   if (AlignedNonVirtualTypeSize == AlignedNextFieldOffset) {
     // We don't need any padding.
-    return;
+    return true;
   }
 
   uint64_t NumBytes = AlignedNonVirtualTypeSize - AlignedNextFieldOffset;
   NonVirtualBaseFieldTypes.push_back(getByteArrayType(NumBytes));
+  return true;
 }
 
 bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
@@ -670,7 +671,10 @@
   if (RD) {
     // We've laid out the non-virtual bases and the fields, now compute the
     // non-virtual base field types.
-    ComputeNonVirtualBaseType(RD);
+    if (!ComputeNonVirtualBaseType(RD)) {
+      assert(!Packed && "Could not layout even with a packed LLVM struct!");
+      return false;
+    }
 
     // And lay out the virtual bases.
     RD->getIndirectPrimaryBases(IndirectPrimaryBases);

Added: cfe/trunk/test/CodeGenCXX/pragma-pack.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/pragma-pack.cpp?rev=121436&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/pragma-pack.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/pragma-pack.cpp Thu Dec  9 18:11:00 2010
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -triple=i686-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Base {
+  virtual ~Base();
+  int x;
+};
+
+#pragma pack(1)
+struct Sub : virtual Base {
+  char c;
+};
+
+// CHECK: %struct.Sub = type <{ i32 (...)**, i8, [8 x i8] }>
+void f(Sub*) { }





More information about the cfe-commits mailing list