x86-32 ABI: Fix crash on return of structure with flexible array

member.

Also, spell bitfield more consistently as bit-field.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70220 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2009-04-27 18:31:32 +00:00
Родитель 4064de9598
Коммит 8e03444e92
2 изменённых файлов: 13 добавлений и 4 удалений

Просмотреть файл

@ -237,7 +237,7 @@ static bool areAllFields32Or64BitBasicType(const RecordDecl *RD,
if (!is32Or64BitBasicType(FD->getType(), Context)) if (!is32Or64BitBasicType(FD->getType(), Context))
return false; return false;
// FIXME: Reject bitfields wholesale; there are two problems, we // FIXME: Reject bit-fields wholesale; there are two problems, we
// don't know how to expand them yet, and the predicate for // don't know how to expand them yet, and the predicate for
// telling if a bitfield still counts as "basic" is more // telling if a bitfield still counts as "basic" is more
// complicated than what we were doing previously. // complicated than what we were doing previously.
@ -342,7 +342,7 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
e = RT->getDecl()->field_end(Context); i != e; ++i) { e = RT->getDecl()->field_end(Context); i != e; ++i) {
const FieldDecl *FD = *i; const FieldDecl *FD = *i;
// FIXME: Reject bitfields wholesale for now; this is incorrect. // FIXME: Reject bit-fields wholesale for now; this is incorrect.
if (FD->isBitField()) if (FD->isBitField())
return false; return false;
@ -385,9 +385,15 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
return ABIArgInfo::getDirect(); return ABIArgInfo::getDirect();
} else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) { } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
// Structures with flexible arrays are always indirect.
if (const RecordType *RT = RetTy->getAsStructureType())
if (RT->getDecl()->hasFlexibleArrayMember())
return ABIArgInfo::getIndirect(0);
// Outside of Darwin, structs and unions are always indirect. // Outside of Darwin, structs and unions are always indirect.
if (!IsDarwin && !RetTy->isAnyComplexType()) if (!IsDarwin && !RetTy->isAnyComplexType())
return ABIArgInfo::getIndirect(0); return ABIArgInfo::getIndirect(0);
// Classify "single element" structs as their element type. // Classify "single element" structs as their element type.
if (const Type *SeltTy = isSingleElementStruct(RetTy, Context)) { if (const Type *SeltTy = isSingleElementStruct(RetTy, Context)) {
if (const BuiltinType *BT = SeltTy->getAsBuiltinType()) { if (const BuiltinType *BT = SeltTy->getAsBuiltinType()) {
@ -766,7 +772,7 @@ void X86_64ABIInfo::classify(QualType Ty,
// AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned // AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned
// fields, it has class MEMORY. // fields, it has class MEMORY.
// //
// Note, skip this test for bitfields, see below. // Note, skip this test for bit-fields, see below.
if (!BitField && Offset % Context.getTypeAlign(i->getType())) { if (!BitField && Offset % Context.getTypeAlign(i->getType())) {
Lo = Memory; Lo = Memory;
return; return;
@ -780,7 +786,7 @@ void X86_64ABIInfo::classify(QualType Ty,
// NO_CLASS. // NO_CLASS.
Class FieldLo, FieldHi; Class FieldLo, FieldHi;
// Bitfields require special handling, they do not force the // Bit-fields require special handling, they do not force the
// structure to be passed in memory even if unaligned, and // structure to be passed in memory even if unaligned, and
// therefore they can straddle an eightbyte. // therefore they can straddle an eightbyte.
if (BitField) { if (BitField) {

Просмотреть файл

@ -123,4 +123,7 @@ struct { struct {} a; struct { float a[1]; } b; } f25(void) {}
struct s26 { struct { char a, b; } a; struct { char a, b } b; } f26(void) {} struct s26 { struct { char a, b; } a; struct { char a, b } b; } f26(void) {}
struct s27 { struct { char a, b, c; } a; struct { char a } b; } f27(void) {} struct s27 { struct { char a, b, c; } a; struct { char a } b; } f27(void) {}
// RUN: grep 'void @f28(%.truct.s28\* noalias sret %agg.result)' %t &&
struct s28 { int a; int b[] } f28(void) {}
// RUN: true // RUN: true