Fix a tail padding bug in the record layout builder code. The bug was found by an...
authorAnders Carlsson <andersca@mac.com>
Mon, 27 Jul 2009 14:55:54 +0000 (14:55 +0000)
committerAnders Carlsson <andersca@mac.com>
Mon, 27 Jul 2009 14:55:54 +0000 (14:55 +0000)
llvm-svn: 77189

clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
clang/lib/CodeGen/CGRecordLayoutBuilder.h

index 7405138..adbfd3f 100644 (file)
@@ -88,6 +88,8 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
   
   AppendBytes(NumBytesToAppend);
   
+  AlignmentAsLLVMStruct = std::max(AlignmentAsLLVMStruct, getTypeAlignment(Ty));
+
   BitsAvailableInLastField = 
     getNextFieldOffsetInBytes() * 8 - (FieldOffset + FieldSize);
 }
@@ -207,12 +209,22 @@ bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
   }
 
   // Append tail padding if necessary.
-  if (Layout.getSize() / 8 > getNextFieldOffsetInBytes())
-    AppendPadding(getNextFieldOffsetInBytes(), AlignmentAsLLVMStruct);
+  AppendTailPadding(Layout.getSize());
   
   return true;
 }
 
+void CGRecordLayoutBuilder::AppendTailPadding(uint64_t RecordSize) {
+  assert(RecordSize % 8 == 0 && "Invalid record size!");
+  
+  uint64_t RecordSizeInBytes = RecordSize / 8;
+  assert(getNextFieldOffsetInBytes() <= RecordSizeInBytes && "Size mismatch!");
+  
+  unsigned NumPadBytes = RecordSizeInBytes - getNextFieldOffsetInBytes();
+  AppendBytes(NumPadBytes);
+}
+
+
 void CGRecordLayoutBuilder::AppendField(uint64_t FieldOffsetInBytes, 
                                         const llvm::Type *FieldTy) {
   AlignmentAsLLVMStruct = std::max(AlignmentAsLLVMStruct,
@@ -256,10 +268,8 @@ void CGRecordLayoutBuilder::AppendBytes(uint64_t NumBytes) {
     return;
   
   const llvm::Type *Ty = llvm::Type::Int8Ty;
-  if (NumBytes > 1) {
-    // FIXME: Use a VMContext.
+  if (NumBytes > 1)
     Ty = llvm::ArrayType::get(Ty, NumBytes);
-  }
   
   // Append the padding field
   AppendField(getNextFieldOffsetInBytes(), Ty);
@@ -294,7 +304,6 @@ CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types,
   // FIXME: Once this works well enough, enable it.
   return 0;
   
-  // FIXME: Use a VMContext.
   const llvm::Type *Ty = llvm::StructType::get(Builder.FieldTypes,
                                                Builder.Packed);
   
index b938785..f236881 100644 (file)
@@ -111,6 +111,10 @@ class CGRecordLayoutBuilder {
   /// AppendBytes - Append a given number of bytes to the record.
   void AppendBytes(uint64_t NumBytes);
 
+  /// AppendTailPadding - Append enough tail padding so that the type will have
+  /// the passed size.
+  void AppendTailPadding(uint64_t RecordSize);
+  
   /// getNextFieldOffsetInBytes - returns where the next field offset is.
   uint64_t getNextFieldOffsetInBytes() const;