зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
4064de9598
Коммит
8e03444e92
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче