]> granicus.if.org Git - clang/commitdiff
x86-32 ABI: Fix crash on return of structure with flexible array
authorDaniel Dunbar <daniel@zuster.org>
Mon, 27 Apr 2009 18:31:32 +0000 (18:31 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Mon, 27 Apr 2009 18:31:32 +0000 (18:31 +0000)
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

lib/CodeGen/CGCall.cpp
test/CodeGen/x86_32-arguments.c

index 41d4d7c90b90fb9c5fb728dddb95462234da0914..07663bfaea4eddaa7daf4479ee5b507104c89baa 100644 (file)
@@ -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) {
index 8d1e5dd8ad1cc4c872ddcb49442226ae328af7b2..95307e929ad73161e35b565eb6671f4724c264a0 100644 (file)
@@ -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