[llvm-commits] [llvm-gcc-4.2] r51866 - /llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
Duncan Sands
baldrick at free.fr
Mon Jun 2 08:56:49 PDT 2008
Author: baldrick
Date: Mon Jun 2 10:56:49 2008
New Revision: 51866
URL: http://llvm.org/viewvc/llvm-project?rev=51866&view=rev
Log:
Fix 2003-10-09-UnionInitializerBug.c on x86-64.
The problem was that in ConvertUNION if the
new field was less aligned than a previous one
but was also the biggest field seen so far then
it was selected. But the most aligned field is
supposed to always be selected. This caused a
crash in ConvertStructFieldInitializerToType
which relies on initializers not being more
aligned than the LLVM type. In the long run
I think ConvertStructFieldInitializerToType
should be modified to not care about the
alignment.
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=51866&r1=51865&r2=51866&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Mon Jun 2 10:56:49 2008
@@ -2179,7 +2179,7 @@
const TargetData &TD = getTargetData();
const Type *UnionTy = 0;
tree GccUnionTy = 0;
- unsigned MaxSize = 0, MaxAlign = 0;
+ unsigned MaxAlignSize = 0, MaxAlign = 0;
for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
if (TREE_CODE(Field) != FIELD_DECL) continue;
// assert(getFieldOffsetInBits(Field) == 0 && "Union with non-zero offset?");
@@ -2233,29 +2233,27 @@
const Type *TheTy = ConvertType(TheGccTy);
unsigned Size = TD.getABITypeSize(TheTy);
unsigned Align = TD.getABITypeAlignment(TheTy);
-
+
adjustPaddingElement(GccUnionTy, TheGccTy);
- // Select TheTy as union type if it meets one of the following criteria
- // 1) UnionTy is 0
- // 2) TheTy alignment is more then UnionTy
- // 3) TheTy size is greater than UnionTy size and TheTy alignment is
- // equal to UnionTy
- // 4) TheTy size is greater then UnionTy size and TheTy is packed
- bool useTheTy = false;
+ // Select TheTy as union type if it is more aligned than any other. If more
+ // than one field achieves the maximum alignment then choose the biggest.
+ bool useTheTy;
if (UnionTy == 0)
useTheTy = true;
+ else if (Align < MaxAlign)
+ useTheTy = false;
else if (Align > MaxAlign)
useTheTy = true;
- else if (MaxAlign == Align && Size > MaxSize)
- useTheTy = true;
- else if (Size > MaxSize)
+ else if (Size > MaxAlignSize)
useTheTy = true;
+ else
+ useTheTy = false;
if (useTheTy) {
UnionTy = TheTy;
GccUnionTy = TheGccTy;
- MaxSize = MAX(MaxSize, Size);
+ MaxAlignSize = Size;
MaxAlign = Align;
}
More information about the llvm-commits
mailing list