From: Eli Friedman Date: Thu, 15 Nov 2012 23:40:48 +0000 (+0000) Subject: Make sure CodeGenTypes correctly reconverts function types. Fixes PR14355, a crash... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=84fd6df966208b380cba072d2f2883962b9d270a;p=clang Make sure CodeGenTypes correctly reconverts function types. Fixes PR14355, a crash in IR generation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168112 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index 3c6c5c9a2e..d7f15a730b 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -453,9 +453,19 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { // cannot lower the function type. if (!isFuncTypeConvertible(FT)) { // This function's type depends on an incomplete tag type. + + // Force conversion of all the relevant record types, to make sure + // we re-convert the FunctionType when appropriate. + if (const RecordType *RT = FT->getResultType()->getAs()) + ConvertRecordDeclType(RT->getDecl()); + if (const FunctionProtoType *FPT = dyn_cast(FT)) + for (unsigned i = 0, e = FPT->getNumArgs(); i != e; i++) + if (const RecordType *RT = FPT->getArgType(i)->getAs()) + ConvertRecordDeclType(RT->getDecl()); + // Return a placeholder type. ResultType = llvm::StructType::get(getLLVMContext()); - + SkippedLayout = true; break; } diff --git a/test/CodeGen/incomplete-function-type-2.c b/test/CodeGen/incomplete-function-type-2.c new file mode 100644 index 0000000000..c6882f6c8a --- /dev/null +++ b/test/CodeGen/incomplete-function-type-2.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s + +// PR14355: don't crash +// Keep this test in its own file because CodeGenTypes has global state. +// CHECK: define void @test10_foo({}* %p1.coerce) nounwind { +struct test10_B; +typedef struct test10_B test10_F3(double); +void test10_foo(test10_F3 p1); +struct test10_B test10_b(double); +void test10_bar() { + test10_foo(test10_b); +} +struct test10_B {}; +void test10_foo(test10_F3 p1) +{ + p1(0.0); +}