[llvm-commits] [llvm-gcc-4.2] r65527 - /llvm-gcc-4.2/trunk/gcc/llvm-types.cpp

Duncan Sands baldrick at free.fr
Thu Feb 26 03:43:59 PST 2009


Author: baldrick
Date: Thu Feb 26 05:43:58 2009
New Revision: 65527

URL: http://llvm.org/viewvc/llvm-project?rev=65527&view=rev
Log:
CopyAggregate copies LLVM structs field by field.
However it doesn't bother copying fields that were
marked isPaddingElement when the type was converted.
Before CopyAggregate is used, a check is made that
no gcc field is living inside structure padding.
But this check only tests for alignment padding and
doesn't consider fields marked isPaddingElement as
being padding!  This can result in some parts of a
gcc field not being copied if they lie inside a field
marked isPaddingElement.  I noticed this with an Ada
testcase, see test/FrontendAda/element_copy.adb, but
presumably it can happen in obscure cases for C too.
The fix is to teach FindLLVMTypePadding about fields
marked isPaddingElement.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=65527&r1=65526&r2=65527&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Thu Feb 26 05:43:58 2009
@@ -518,44 +518,42 @@
 
 /// FindLLVMTypePadding - If the specified struct has any inter-element padding,
 /// add it to the Padding array.
-static void FindLLVMTypePadding(const Type *Ty, uint64_t BitOffset,
+static void FindLLVMTypePadding(const Type *Ty, tree type, uint64_t BitOffset,
                        SmallVector<std::pair<uint64_t,uint64_t>, 16> &Padding) {
   if (const StructType *STy = dyn_cast<StructType>(Ty)) {
     const TargetData &TD = getTargetData();
     const StructLayout *SL = TD.getStructLayout(STy);
-    uint64_t PrevFieldBitOffset = 0;
+    uint64_t PrevFieldEnd = 0;
     for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+      // If this field is marked as being padding, then pretend it is not there.
+      // This results in it (or something bigger) being added to Padding.  This
+      // matches the logic in CopyAggregate.
+      if (type && isPaddingElement(type, i))
+        continue;
+
       uint64_t FieldBitOffset = SL->getElementOffset(i)*8;
 
       // Get padding of sub-elements.
-      FindLLVMTypePadding(STy->getElementType(i), 
+      FindLLVMTypePadding(STy->getElementType(i), 0,
                           BitOffset+FieldBitOffset, Padding);
       // Check to see if there is any padding between this element and the
       // previous one.
-      if (i) {
-        uint64_t PrevFieldEnd = 
-          PrevFieldBitOffset+TD.getTypeSizeInBits(STy->getElementType(i-1));
-        if (PrevFieldEnd < FieldBitOffset)
-          Padding.push_back(std::make_pair(PrevFieldEnd+BitOffset,
-                                           FieldBitOffset-PrevFieldEnd));
-      }
-      
-      PrevFieldBitOffset = FieldBitOffset;
+      if (PrevFieldEnd < FieldBitOffset)
+        Padding.push_back(std::make_pair(PrevFieldEnd+BitOffset,
+                                         FieldBitOffset-PrevFieldEnd));
+      PrevFieldEnd =
+        FieldBitOffset + TD.getTypeSizeInBits(STy->getElementType(i));
     }
-    
+
     //  Check for tail padding.
-    if (unsigned EltCount = STy->getNumElements()) {
-      uint64_t PrevFieldEnd = PrevFieldBitOffset +
-           TD.getTypeSizeInBits(STy->getElementType(EltCount-1));
-      if (PrevFieldEnd < SL->getSizeInBytes()*8)
-        Padding.push_back(std::make_pair(PrevFieldEnd,
-                                         SL->getSizeInBytes()*8-PrevFieldEnd));
-    }
-    
+    if (PrevFieldEnd < SL->getSizeInBits())
+      Padding.push_back(std::make_pair(PrevFieldEnd,
+                                       SL->getSizeInBits()-PrevFieldEnd));
   } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
     uint64_t EltSize = getTargetData().getTypeSizeInBits(ATy->getElementType());
     for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
-      FindLLVMTypePadding(ATy->getElementType(), BitOffset+i*EltSize, Padding);
+      FindLLVMTypePadding(ATy->getElementType(), 0, BitOffset+i*EltSize,
+                          Padding);
   }
   
   // primitive and vector types have no padding.
@@ -696,7 +694,7 @@
   
   // Start by finding all of the padding in the LLVM Type.
   SmallVector<std::pair<uint64_t,uint64_t>, 16> StructPadding;
-  FindLLVMTypePadding(Ty, 0, StructPadding);
+  FindLLVMTypePadding(Ty, type, 0, StructPadding);
   
   for (unsigned i = 0, e = StructPadding.size(); i != e; ++i)
     if (GCCTypeOverlapsWithPadding(type, StructPadding[i].first,





More information about the llvm-commits mailing list