From: Eli Friedman Date: Thu, 5 Mar 2009 04:18:07 +0000 (+0000) Subject: Make IRGen compatible with declaring a function with incomplete X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2136b2e9345c23c26426110873dd97ef5d761ef2;p=clang Make IRGen compatible with declaring a function with incomplete return/argument types. (The generated IR isn't ideal, but we can't really do better in general.) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66132 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 422415c2e2..a187f8a51b 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -779,13 +779,24 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { llvm::GlobalValue * CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D, const llvm::Type *Ty) { - if (!Ty) + bool DoSetAttributes = true; + if (!Ty) { Ty = getTypes().ConvertType(D->getType()); + if (!isa(Ty)) { + // This function doesn't have a complete type (for example, the return + // type is an incomplete struct). Use a fake type instead, and make + // sure not to try to set attributes. + Ty = llvm::FunctionType::get(llvm::Type::VoidTy, + std::vector(), false); + DoSetAttributes = false; + } + } llvm::Function *F = llvm::Function::Create(cast(Ty), llvm::Function::ExternalLinkage, getMangledName(D), &getModule()); - SetFunctionAttributes(D, F); + if (DoSetAttributes) + SetFunctionAttributes(D, F); return F; } diff --git a/test/CodeGen/incomplete-function-type.c b/test/CodeGen/incomplete-function-type.c index 6bd872b725..09e08d729c 100644 --- a/test/CodeGen/incomplete-function-type.c +++ b/test/CodeGen/incomplete-function-type.c @@ -1,9 +1,9 @@ // RUN: clang -emit-llvm %s -o - | not grep opaque -enum teste1 (*test1)(void); -struct tests2 (*test2)(); +enum teste1 test1f(void), (*test1)(void) = test1f; +struct tests2 test2f(), (*test2)() = test2f; struct tests3; -void (*test3)(struct tests3); +void test3f(struct tests3), (*test3)(struct tests3) = test3f; enum teste1 { TEST1 }; struct tests2 { int x,y,z,a,b,c,d,e,f,g; }; struct tests3 { float x; };