From 55e59e139d9ebcaae16d710472e28edbcafac98a Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 24 Sep 2009 05:12:36 +0000 Subject: [PATCH] Darwin/x86-32: Enumerated types and block pointer types in structures were not handled correctly. - Function arguments incorrect when function returns a struct on i386 w/ llvm-g++ and clang git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82681 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TargetABIInfo.cpp | 10 +++++--- test/CodeGen/x86_32-arguments.c | 45 ++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/CodeGen/TargetABIInfo.cpp b/lib/CodeGen/TargetABIInfo.cpp index 3ad8cfc36f..da30060ecd 100644 --- a/lib/CodeGen/TargetABIInfo.cpp +++ b/lib/CodeGen/TargetABIInfo.cpp @@ -159,7 +159,9 @@ static const Type *isSingleElementStruct(QualType T, ASTContext &Context) { } static bool is32Or64BitBasicType(QualType Ty, ASTContext &Context) { - if (!Ty->getAs() && !Ty->isPointerType()) + if (!Ty->getAs() && !Ty->isAnyPointerType() && + !Ty->isAnyComplexType() && !Ty->isEnumeralType() && + !Ty->isBlockPointerType()) return false; uint64_t Size = Context.getTypeSize(Ty); @@ -291,8 +293,10 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty, return true; } - // If this is a builtin, pointer, or complex type, it is ok. - if (Ty->getAs() || Ty->isPointerType() || Ty->isAnyComplexType()) + // If this is a builtin, pointer, enum, or complex type, it is ok. + if (Ty->getAs() || Ty->isAnyPointerType() || + Ty->isAnyComplexType() || Ty->isEnumeralType() || + Ty->isBlockPointerType()) return true; // Arrays are treated like records. diff --git a/test/CodeGen/x86_32-arguments.c b/test/CodeGen/x86_32-arguments.c index 7464595dce..78fb8342ee 100644 --- a/test/CodeGen/x86_32-arguments.c +++ b/test/CodeGen/x86_32-arguments.c @@ -1,4 +1,4 @@ -// RUN: clang-cc -triple i386-apple-darwin9 -emit-llvm -o %t %s && +// RUN: clang-cc -fblocks -triple i386-apple-darwin9 -emit-llvm -o %t %s && // RUN: grep 'define signext i8 @f0()' %t && // RUN: grep 'define signext i16 @f1()' %t && // RUN: grep 'define i32 @f2()' %t && @@ -159,4 +159,47 @@ typedef int v39 __attribute((vector_size(16))); struct s39 { v39 x; }; void f39(struct s39 x) {} +// +// RUN: grep 'define i32 @f40()' %t && +enum e40 { ec0 = 0 }; +enum e40 f40(void) { } + +// RUN: grep 'define void ()\* @f41()' %t && +typedef void (^vvbp)(void); +vvbp f41(void) { } + +// RUN: grep 'define i32 @f42()' %t && +struct s42 { enum e40 f0; } f42(void) { } + +// RUN: grep 'define i64 @f43()' %t && +struct s43 { enum e40 f0; int f1; } f43(void) { } + +// RUN: grep 'define i32 @f44()' %t && +struct s44 { vvbp f0; } f44(void) { } + +// RUN: grep 'define i64 @f45()' %t && +struct s45 { vvbp f0; int f1; } f45(void) { } + +// RUN: grep 'define void @f46(i32 %a0)' %t && +void f46(enum e40 a0) { } + +// RUN: grep 'define void @f47(void ()\* %a1)' %t && +void f47(vvbp a1) { } + +// RUN: grep 'define void @f48(i32 %a0.0)' %t && +struct s48 { enum e40 f0; }; +void f48(struct s48 a0) { } + +// RUN: grep 'define void @f49(i32 %a0.0, i32 %a0.1)' %t && +struct s49 { enum e40 f0; int f1; }; +void f49(struct s49 a0) { } + +// RUN: grep 'define void @f50(void ()\* %a0.0)' %t && +struct s50 { vvbp f0; }; +void f50(struct s50 a0) { } + +// RUN: grep 'define void @f51(void ()\* %a0.0, i32 %a0.1)' %t && +struct s51 { vvbp f0; int f1; }; +void f51(struct s51 a0) { } + // RUN: true -- 2.40.0