From: Eli Friedman Date: Mon, 1 Jun 2009 10:04:20 +0000 (+0000) Subject: PR4289: Make sure "&func" has the right LLVM type when "func" is a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3fbc473e1e76ead199c7333bdbf02dfa1c7dc420;p=clang PR4289: Make sure "&func" has the right LLVM type when "func" is a K&R-style definition. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72690 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index da3f79e83a..155658e92d 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -711,8 +711,20 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { LV.SetGlobalObjCRef(LV, true); return LV; } else if (const FunctionDecl *FD = dyn_cast(E->getDecl())) { - return LValue::MakeAddr(CGM.GetAddrOfFunction(GlobalDecl(FD)), - E->getType().getCVRQualifiers(), + llvm::Value* V = CGM.GetAddrOfFunction(GlobalDecl(FD)); + if (!FD->hasPrototype()) { + if (const FunctionProtoType *Proto = + FD->getType()->getAsFunctionProtoType()) { + // Ugly case: for a K&R-style definition, the type of the definition + // isn't the same as the type of a use. Correct for this with a + // bitcast. + QualType NoProtoType = + getContext().getFunctionNoProtoType(Proto->getResultType()); + NoProtoType = getContext().getPointerType(NoProtoType); + V = Builder.CreateBitCast(V, ConvertType(NoProtoType), "tmp"); + } + } + return LValue::MakeAddr(V, E->getType().getCVRQualifiers(), getContext().getObjCGCAttrKind(E->getType())); } else if (const ImplicitParamDecl *IPD = diff --git a/test/CodeGen/2009-06-01-addrofknr.c b/test/CodeGen/2009-06-01-addrofknr.c new file mode 100644 index 0000000000..16a5bbffc3 --- /dev/null +++ b/test/CodeGen/2009-06-01-addrofknr.c @@ -0,0 +1,21 @@ +// RUN: clang-cc %s -o %t -emit-llvm -verify +// PR4289 + +struct funcptr { + int (*func)(); +}; + +static int func(f) + void *f; +{ +} + +int +main(int argc, char *argv[]) +{ + struct funcptr fp; + + fp.func = &func; + fp.func = func; +} +