The testcase: struct Z { int :1; int :0; int :1; } z;
The zero width field causes the second :1 field to start at bit 32. This requires inserting 24 bits of padding. For some obscure reason the padding logic subtracts the number of bits of padding from the new field size before adding it, meaning that it tries to add -23 new bits rather than +1, causing an assertion failure. With the attached patch struct Z converts to %struct.Z = type { i8, [3 x i8], i8 } Lightly tested. Ciao, Duncan.
Index: gcc.llvm/gcc/llvm-types.cpp =================================================================== --- gcc.llvm.orig/gcc/llvm-types.cpp 2007-04-17 21:22:37.000000000 +0200 +++ gcc.llvm/gcc/llvm-types.cpp 2007-04-17 22:17:11.000000000 +0200 @@ -1184,7 +1184,7 @@ } } -// Add new element which is a bit field. Size is not the size of bit filed, +// Add new element which is a bit field. Size is not the size of bit field, // but size of bits required to determine type of new Field which will be // used to access this bit field. void StructTypeConversionInfo::addNewBitField(unsigned Size, @@ -1192,7 +1192,7 @@ // Figure out the LLVM type that we will use for the new field. // Note, Size is not necessarily size of the new field. It indicates - // additional bits required after FirstunallocatedByte to cover new field. + // additional bits required after FirstUnallocatedByte to cover new field. const Type *NewFieldTy; if (Size <= 8) NewFieldTy = Type::Int8Ty; @@ -1368,22 +1368,21 @@ if (StartOffsetInBits > FirstUnallocatedByte*8) { // If there is padding between the last field and the struct, insert // explicit bytes into the field to represent it. - unsigned PadBytes = 0; - unsigned PadBits = 0; - if (StartOffsetFromByteBoundry != 0) { - // New field does not start at byte boundry. - PadBits = StartOffsetInBits - (FirstUnallocatedByte*8); - PadBytes = PadBits/8 + 1; + unsigned PadBytes = StartOffsetInBits/8-FirstUnallocatedByte; + if (PadBytes > 0) { + const Type *Pad = Type::Int8Ty; + if (PadBytes != 1) + Pad = ArrayType::get(Pad, PadBytes); + Info.addElement(Pad, FirstUnallocatedByte, PadBytes); } - - PadBytes += StartOffsetInBits/8-FirstUnallocatedByte; - const Type *Pad = Type::Int8Ty; - if (PadBytes != 1) - Pad = ArrayType::get(Pad, PadBytes); - Info.addElement(Pad, FirstUnallocatedByte, PadBytes); FirstUnallocatedByte = StartOffsetInBits/8; - // This field will use some of the bits from this PadBytes. - FieldSizeInBits = FieldSizeInBits - (PadBytes*8 - PadBits); + if (StartOffsetFromByteBoundry > 0) { + // New field does not start at byte boundry. + // Create a byte for the start to live in and try again. + Info.addElement(Type::Int8Ty, FirstUnallocatedByte, 1); + DecodeStructBitField(Field, Info); + return; + } } // Now, Field starts at FirstUnallocatedByte and everything is aligned.
// RUN: %llvmgcc %s -S -o - // PR1332 struct Z { int :1; int :0; int :1; } z;
_______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits