PR4289: Make sure "&func" has the right LLVM type when "func" is a

K&R-style definition.

llvm-svn: 72690
This commit is contained in:
Eli Friedman 2009-06-01 10:04:20 +00:00
parent fcbf7d2baf
commit e32c02114f
2 changed files with 35 additions and 2 deletions

View File

@ -711,8 +711,20 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
LV.SetGlobalObjCRef(LV, true); LV.SetGlobalObjCRef(LV, true);
return LV; return LV;
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) { } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
return LValue::MakeAddr(CGM.GetAddrOfFunction(GlobalDecl(FD)), llvm::Value* V = CGM.GetAddrOfFunction(GlobalDecl(FD));
E->getType().getCVRQualifiers(), 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())); getContext().getObjCGCAttrKind(E->getType()));
} }
else if (const ImplicitParamDecl *IPD = else if (const ImplicitParamDecl *IPD =

View File

@ -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;
}