Something in this patch broke the llvm-gcc compilation on arm-linux:

/home/laurov/llvm/llvm-gcc/build/gcc/xgcc
-B/home/laurov/llvm/llvm-gcc/build/gcc/
-B/usr/local/arm-linux-gnueabi/bin/
-B/usr/local/arm-linux-gnueabi/lib/ -isystem
/usr/local/arm-linux-gnueabi/include -isystem
/usr/local/arm-linux-gnueabi/sys-include -O2  -DIN_GCC    -W -Wall
-Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes
-Wold-style-definition  -isystem ./include  -fPIC -g
-DHAVE_GTHR_DEFAULT -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED  -I. -I.
-I/home/laurov/llvm/llvm-gcc/gcc -I/home/laurov/llvm/llvm-gcc/gcc/.
-I/home/laurov/llvm/llvm-gcc/gcc/../include
-I/home/laurov/llvm/llvm-gcc/gcc/../libcpp/include
-I/home/laurov/llvm/llvm/include
-I/home/laurov/llvm/llvm/build//include -fexceptions  -c
/home/laurov/llvm/llvm-gcc/gcc/config/arm/unwind-arm.c -o
libgcc/./unwind-arm.o
cc1: /home/laurov/llvm/llvm-gcc/gcc/llvm-types.cpp:968: unsigned int
StructTypeConversionInfo::getLLVMFieldFor(uint64_t, unsigned int&,
bool): Assertion `0 && "Could not find field!"' failed.
/home/laurov/llvm/llvm-gcc/gcc/config/arm/unwind-arm.c: In function
'_Unwind_Complete':
/home/laurov/llvm/llvm-gcc/gcc/config/arm/unwind-arm.c:582: internal
compiler error: Aborted
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://llvm.org/bugs> for instructions.
make[2]: *** [libgcc/./unwind-arm.o] Error 1



This bug can be reproduced using llvm-gcc for i386:

[EMAIL PROTECTED]:/tmp$ llvm-gcc unwind-arm.c
cc1: ../../gcc/llvm-types.cpp:968: unsigned int
StructTypeConversionInfo::getLLVMFieldFor(uint64_t, unsigned int&,
bool): Assertion `0 && "Could not find field!"' failed.
unwind-arm.c: In function 'get_eit_entry':
unwind-arm.c:382: internal compiler error: Aborted
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://llvm.org/bugs> for instructions.

Lauro


2007/3/19, [EMAIL PROTECTED] <[EMAIL PROTECTED]>:
Revision: 125160
Author:   dpatel
Date:     2007-03-19 13:55:02 -0700 (Mon, 19 Mar 2007)

Log Message:
-----------
Better support for variable size struct fields.
Patch by Duncan Sands.

Modified Paths:
--------------
    apple-local/branches/llvm/gcc/llvm-convert.cpp
    apple-local/branches/llvm/gcc/llvm-types.cpp

Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-convert.cpp      2007-03-19 19:06:59 UTC 
(rev 125159)
+++ apple-local/branches/llvm/gcc/llvm-convert.cpp      2007-03-19 20:55:02 UTC 
(rev 125160)
@@ -4660,12 +4660,6 @@
     assert(DECL_LLVM_SET_P(FieldDecl) && "Struct not laid out for LLVM?");
     ConstantInt *CI = cast<ConstantInt>(DECL_LLVM(FieldDecl));
     uint32_t MemberIndex = CI->getZExtValue();
-    if (MemberIndex == ~0U) {
-      assert(isStructWithVarSizeArrayAtEnd(StructTy) &&
-             "Isn't var sized array access!");
-      CI = ConstantInt::get(Type::Int32Ty, StructTy->getNumContainedTypes()-1);
-      MemberIndex = CI->getZExtValue();
-    }
     assert(MemberIndex < StructTy->getNumContainedTypes() &&
            "Field Idx out of range!");
     FieldPtr = new GetElementPtrInst(StructAddrLV.Ptr,
@@ -5476,35 +5470,32 @@
       // If not, things are much simpler.
       assert(DECL_LLVM_SET_P(Field) && "Struct not laid out for LLVM?");
       unsigned FieldNo = cast<ConstantInt>(DECL_LLVM(Field))->getZExtValue();
-
+      assert(FieldNo < ResultElts.size() && "Invalid struct field number!");
+
+      // Example: struct X { int A; char C[]; } x = { 4, "foo" };
+      assert(TYPE_SIZE(TREE_TYPE(Field)) ||
+             (FieldNo == ResultElts.size()-1 &&
+              isStructWithVarSizeArrayAtEnd(STy))
+             && "field with no size is not array at end of struct!");
+
       // If this is an initialization of a global that ends with a variable
       // sized array at its end, and the initializer has a non-zero number of
-      // elements, we must handle this case now.  In this case, FieldNo is ~0U
-      // and Val contains the actual type for the array.
-      if (FieldNo == ~0U) {
-        // Handle: struct X { int A; char C[]; } x = { 4, "foo" };
-        assert(isStructWithVarSizeArrayAtEnd(STy) &&
-               "Struct doesn't end with variable sized array!");
-        FieldNo = STy->getNumElements()-1;
-        ResultElts[FieldNo] = Val;
-      } else {
-        assert(FieldNo < ResultElts.size() && "Invalid struct field number!");
-
-        // Otherwise, we know that the initializer has to match the element 
type
-        // of the LLVM structure field.  If not, then there is something that 
is
-        // not straight-forward going on.  For example, we could be 
initializing
-        // an unaligned integer field (e.g. due to attribute packed) with an
-        // integer.  The struct field will have type [4 x ubyte] instead of
-        // "int" for example.  If we ignored this, we would lay out the
-        // initializer wrong.
-        if (Val->getType() != STy->getElementType(FieldNo))
-          Val = ConvertStructFieldInitializerToType(Val,
+      // elements, then Val contains the actual type for the array.  Otherwise,
+      // we know that the initializer has to match the element type of the LLVM
+      // structure field.  If not, then there is something that is not
+      // straight-forward going on.  For example, we could be initializing an
+      // unaligned integer field (e.g. due to attribute packed) with an
+      // integer.  The struct field will have type [4 x ubyte] instead of
+      // "int" for example.  If we ignored this, we would lay out the
+      // initializer wrong.
+      if (TYPE_SIZE(TREE_TYPE(Field)) &&
+          Val->getType() != STy->getElementType(FieldNo))
+        Val = ConvertStructFieldInitializerToType(Val,
                                                   
STy->getElementType(FieldNo));

-        ResultElts[FieldNo] = Val;
-      }
+      ResultElts[FieldNo] = Val;
     }
-
+
     NextField = TREE_CHAIN(Field);
   }

@@ -5716,31 +5707,18 @@
     ConstantInt *CI = cast<ConstantInt>(DECL_LLVM(FieldDecl));
     uint64_t MemberIndex = CI->getZExtValue();

-    if (MemberIndex  != ~0U) {
-      std::vector<Value*> Idxs;
-      Idxs.push_back(Constant::getNullValue(Type::Int32Ty));
-      Idxs.push_back(CI);
-      FieldPtr = ConstantExpr::getGetElementPtr(StructAddrLV, &Idxs[0],
-                                                Idxs.size());
-
-      // Now that we did an offset from the start of the struct, subtract off
-      // the offset from BitStart.
-      if (MemberIndex) {
-        const StructLayout *SL = 
TD.getStructLayout(cast<StructType>(StructTy));
-        BitStart -= SL->getElementOffset(MemberIndex) * 8;
-      }
-    } else {
-      // We were unable to make a nice offset, emit an ugly one.
-      Constant *Offset = Convert(field_offset);
-      FieldPtr = ConstantExpr::getPtrToInt(StructAddrLV, Offset->getType());
-      FieldPtr = ConstantExpr::getAdd(FieldPtr, Offset);
-      FieldPtr = ConstantExpr::getIntToPtr(FieldPtr, 
PointerType::get(FieldTy));
-
-      // Do horrible pointer arithmetic to get the address of the field.
-      unsigned ByteOffset = TREE_INT_CST_LOW(field_offset);
-      BitStart -= ByteOffset * 8;
-    }
+    std::vector<Value*> Idxs;
+    Idxs.push_back(Constant::getNullValue(Type::Int32Ty));
+    Idxs.push_back(CI);
+    FieldPtr = ConstantExpr::getGetElementPtr(StructAddrLV, &Idxs[0],
+                                              Idxs.size());

+    // Now that we did an offset from the start of the struct, subtract off
+    // the offset from BitStart.
+    if (MemberIndex) {
+      const StructLayout *SL = TD.getStructLayout(cast<StructType>(StructTy));
+      BitStart -= SL->getElementOffset(MemberIndex) * 8;
+    }
   } else {
     Constant *Offset = Convert(field_offset);
     Constant *Ptr = ConstantExpr::getPtrToInt(StructAddrLV, Offset->getType());

Modified: apple-local/branches/llvm/gcc/llvm-types.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-types.cpp        2007-03-19 19:06:59 UTC 
(rev 125159)
+++ apple-local/branches/llvm/gcc/llvm-types.cpp        2007-03-19 20:55:02 UTC 
(rev 125160)
@@ -962,8 +962,11 @@
       while (CurFieldNo < ElementOffsetInBytes.size() &&
              getFieldEndOffsetInBytes(CurFieldNo)*8 <= FieldOffsetInBits)
         ++CurFieldNo;
-      if (CurFieldNo >= ElementOffsetInBytes.size()) return ~0U;
-      return CurFieldNo;
+      if (CurFieldNo < ElementOffsetInBytes.size())
+        return CurFieldNo;
+      // Otherwise, we couldn't find the field!
+      assert(0 && "Could not find field!");
+      return ~0U;
     }

     // Handle zero sized fields now.  If the next field is zero sized, return
@@ -1009,28 +1012,15 @@
   return Result;
 }

-/// isNotLastField - Return true if this is not the last field in its record.
-///
-static bool isNotLastField(tree Field) {
-  for (Field = TREE_CHAIN(Field); Field; Field = TREE_CHAIN(Field))
-    if (TREE_CODE(Field) == FIELD_DECL)
-      return true;
-  return false;
-}
-
-
 /// DecodeStructFields - This method decodes the specified field, if it is a
 /// FIELD_DECL, adding or updating the specified StructTypeConversionInfo to
 /// reflect it.
 void TypeConverter::DecodeStructFields(tree Field,
                                        StructTypeConversionInfo &Info) {
   if (TREE_CODE(Field) != FIELD_DECL ||
-      // Don't include variable sized fields, doing so would break anything
-      // after them... unless this is the last field.
-      ((TYPE_SIZE(TREE_TYPE(Field)) == 0 ||
-        TREE_CODE(TYPE_SIZE(TREE_TYPE(Field))) != INTEGER_CST) &&
-       isNotLastField(Field))) return;
-
+      TREE_CODE(DECL_FIELD_OFFSET(Field)) != INTEGER_CST)
+    return;
+
   // Handle bit-fields specially.
   if (DECL_BIT_FIELD_TYPE(Field)) {
     DecodeStructBitField(Field, Info);
@@ -1218,12 +1208,8 @@
   // variable offset.
   unsigned CurFieldNo = 0;
   for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field))
-    if (TREE_CODE(Field) == FIELD_DECL) {
-      // If this field comes after a variable sized element, stop trying to
-      // assign DECL_LLVM's.
-      if (TREE_CODE(DECL_FIELD_OFFSET(Field)) != INTEGER_CST)
-        break;
-
+    if (TREE_CODE(Field) == FIELD_DECL &&
+        TREE_CODE(DECL_FIELD_OFFSET(Field)) == INTEGER_CST) {
       unsigned FieldOffsetInBits = getFieldOffsetInBits(Field);
       tree FieldType = TREE_TYPE(Field);

@@ -1241,10 +1227,9 @@

       // Figure out if this field is zero bits wide, e.g. {} or [0 x int].  Do
       // not include variable sized fields here.
-      bool isZeroSizeField =
-        TYPE_SIZE(FieldType) && TREE_CODE(TYPE_SIZE(FieldType)) == 
INTEGER_CST&&
-        TREE_INT_CST_LOW(TYPE_SIZE(FieldType)) == 0;
-
+      bool isZeroSizeField = !TYPE_SIZE(FieldType) ||
+        integer_zerop(TYPE_SIZE(FieldType));
+
       unsigned FieldNo =
         Info.getLLVMFieldFor(FieldOffsetInBits, CurFieldNo, isZeroSizeField);
       SET_DECL_LLVM(Field, ConstantInt::get(Type::Int32Ty, FieldNo));


_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Attachment: unwind-arm.tar.bz2
Description: BZip2 compressed data

_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to