]> granicus.if.org Git - clang/commitdiff
Make sure CodeGenTypes correctly reconverts function types. Fixes PR14355, a crash...
authorEli Friedman <eli.friedman@gmail.com>
Thu, 15 Nov 2012 23:40:48 +0000 (23:40 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Thu, 15 Nov 2012 23:40:48 +0000 (23:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168112 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenTypes.cpp
test/CodeGen/incomplete-function-type-2.c [new file with mode: 0644]

index 3c6c5c9a2e2f2c02318a26214e4d4aeedd83acc5..d7f15a730bf5799fce3100abf001abfd74ecb2e3 100644 (file)
@@ -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<RecordType>())
+        ConvertRecordDeclType(RT->getDecl());
+      if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT))
+        for (unsigned i = 0, e = FPT->getNumArgs(); i != e; i++)
+          if (const RecordType *RT = FPT->getArgType(i)->getAs<RecordType>())
+            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 (file)
index 0000000..c6882f6
--- /dev/null
@@ -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);
+}