From: Daniel Dunbar Date: Mon, 27 Apr 2009 18:31:32 +0000 (+0000) Subject: x86-32 ABI: Fix crash on return of structure with flexible array X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8e03444e924665d4d90f5cfc0624c815256e0309;p=clang 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 --- diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 41d4d7c90b..07663bfaea 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -237,7 +237,7 @@ static bool areAllFields32Or64BitBasicType(const RecordDecl *RD, if (!is32Or64BitBasicType(FD->getType(), Context)) 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 // telling if a bitfield still counts as "basic" is more // 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) { 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()) return false; @@ -385,9 +385,15 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, return ABIArgInfo::getDirect(); } 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. if (!IsDarwin && !RetTy->isAnyComplexType()) return ABIArgInfo::getIndirect(0); + // Classify "single element" structs as their element type. if (const Type *SeltTy = isSingleElementStruct(RetTy, Context)) { 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 // 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())) { Lo = Memory; return; @@ -780,7 +786,7 @@ void X86_64ABIInfo::classify(QualType Ty, // NO_CLASS. 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 // therefore they can straddle an eightbyte. if (BitField) { diff --git a/test/CodeGen/x86_32-arguments.c b/test/CodeGen/x86_32-arguments.c index 8d1e5dd8ad..95307e929a 100644 --- a/test/CodeGen/x86_32-arguments.c +++ b/test/CodeGen/x86_32-arguments.c @@ -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 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