Pass the function type instead of the return type to FunctionDecl::Create

Fix places where the return type of a FunctionDecl was being used in
place of the function type

FunctionDecl::Create() takes as its T parameter the type of function
that should be created, not the return type. Passing in the return type
looks to have been copypasta'd around a bit, but the number of correct
usages outweighs the incorrect ones so I've opted for keeping what T is
the same and fixing up the call sites instead.

This fixes a crash in Clang when attempting to compile the following
snippet of code with -fblocks -fsanitize=function -x objective-c++ (my
original repro case):

  void g(void(^)());
  void f()
  {
      __block int a = 0;
        g(^(){ a++; });
  }

as well as the following which only requires -fsanitize=function -x c++:

  void f(char * buf)
  {
      __builtin_os_log_format(buf, "");
  }

Patch by: Ben (bobsayshilol)

Differential revision: https://reviews.llvm.org/D53263

llvm-svn: 346601
This commit is contained in:
Jonas Devlieghere 2018-11-11 00:56:15 +00:00
parent d23cdbbeb2
commit 64a2630825
9 changed files with 123 additions and 97 deletions

View File

@ -2652,6 +2652,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
StartLoc),
DeclContext(DK), redeclarable_base(C), ODRHash(0),
EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {
assert(T.isNull() || T->isFunctionType());
setStorageClass(S);
setInlineSpecified(isInlineSpecified);
setExplicitSpecified(false);

View File

@ -2008,16 +2008,16 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
ASTContext &C = getContext();
QualType ReturnTy = C.VoidTy;
FunctionArgList args;
ImplicitParamDecl DstDecl(getContext(), C.VoidPtrTy,
ImplicitParamDecl::Other);
ImplicitParamDecl DstDecl(C, C.VoidPtrTy, ImplicitParamDecl::Other);
args.push_back(&DstDecl);
ImplicitParamDecl SrcDecl(getContext(), C.VoidPtrTy,
ImplicitParamDecl::Other);
ImplicitParamDecl SrcDecl(C, C.VoidPtrTy, ImplicitParamDecl::Other);
args.push_back(&SrcDecl);
const CGFunctionInfo &FI =
CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args);
CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);
// FIXME: it would be nice if these were mergeable with things with
// identical semantics.
@ -2027,20 +2027,20 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,
FuncName, &CGM.getModule());
IdentifierInfo *II
= &CGM.getContext().Idents.get(FuncName);
IdentifierInfo *II = &C.Idents.get(FuncName);
FunctionDecl *FD = FunctionDecl::Create(C,
C.getTranslationUnitDecl(),
SourceLocation(),
SourceLocation(), II, C.VoidTy,
nullptr, SC_Static,
false,
false);
SmallVector<QualType, 2> ArgTys;
ArgTys.push_back(C.VoidPtrTy);
ArgTys.push_back(C.VoidPtrTy);
QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
FunctionDecl *FD = FunctionDecl::Create(
C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
FunctionTy, nullptr, SC_Static, false, false);
setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI,
CGM);
StartFunction(FD, C.VoidTy, Fn, FI, args);
StartFunction(FD, ReturnTy, Fn, FI, args);
ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getBeginLoc()};
llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
@ -2201,13 +2201,14 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {
ASTContext &C = getContext();
QualType ReturnTy = C.VoidTy;
FunctionArgList args;
ImplicitParamDecl SrcDecl(getContext(), C.VoidPtrTy,
ImplicitParamDecl::Other);
ImplicitParamDecl SrcDecl(C, C.VoidPtrTy, ImplicitParamDecl::Other);
args.push_back(&SrcDecl);
const CGFunctionInfo &FI =
CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args);
CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);
// FIXME: We'd like to put these into a mergable by content, with
// internal linkage.
@ -2217,18 +2218,19 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {
llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,
FuncName, &CGM.getModule());
IdentifierInfo *II
= &CGM.getContext().Idents.get(FuncName);
IdentifierInfo *II = &C.Idents.get(FuncName);
FunctionDecl *FD = FunctionDecl::Create(C, C.getTranslationUnitDecl(),
SourceLocation(),
SourceLocation(), II, C.VoidTy,
nullptr, SC_Static,
false, false);
SmallVector<QualType, 1> ArgTys;
ArgTys.push_back(C.VoidPtrTy);
QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
FunctionDecl *FD = FunctionDecl::Create(
C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
FunctionTy, nullptr, SC_Static, false, false);
setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI,
CGM);
StartFunction(FD, C.VoidTy, Fn, FI, args);
StartFunction(FD, ReturnTy, Fn, FI, args);
markAsIgnoreThreadCheckingAtRuntime(Fn);
ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getBeginLoc()};
@ -2447,19 +2449,17 @@ generateByrefCopyHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo,
BlockByrefHelpers &generator) {
ASTContext &Context = CGF.getContext();
QualType R = Context.VoidTy;
QualType ReturnTy = Context.VoidTy;
FunctionArgList args;
ImplicitParamDecl Dst(CGF.getContext(), Context.VoidPtrTy,
ImplicitParamDecl::Other);
ImplicitParamDecl Dst(Context, Context.VoidPtrTy, ImplicitParamDecl::Other);
args.push_back(&Dst);
ImplicitParamDecl Src(CGF.getContext(), Context.VoidPtrTy,
ImplicitParamDecl::Other);
ImplicitParamDecl Src(Context, Context.VoidPtrTy, ImplicitParamDecl::Other);
args.push_back(&Src);
const CGFunctionInfo &FI =
CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(R, args);
CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);
llvm::FunctionType *LTy = CGF.CGM.getTypes().GetFunctionType(FI);
@ -2472,16 +2472,18 @@ generateByrefCopyHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo,
IdentifierInfo *II
= &Context.Idents.get("__Block_byref_object_copy_");
FunctionDecl *FD = FunctionDecl::Create(Context,
Context.getTranslationUnitDecl(),
SourceLocation(),
SourceLocation(), II, R, nullptr,
SC_Static,
false, false);
SmallVector<QualType, 2> ArgTys;
ArgTys.push_back(Context.VoidPtrTy);
ArgTys.push_back(Context.VoidPtrTy);
QualType FunctionTy = Context.getFunctionType(ReturnTy, ArgTys, {});
FunctionDecl *FD = FunctionDecl::Create(
Context, Context.getTranslationUnitDecl(), SourceLocation(),
SourceLocation(), II, FunctionTy, nullptr, SC_Static, false, false);
CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
CGF.StartFunction(FD, R, Fn, FI, args);
CGF.StartFunction(FD, ReturnTy, Fn, FI, args);
if (generator.needsCopy()) {
llvm::Type *byrefPtrType = byrefInfo.Type->getPointerTo(0);
@ -2546,12 +2548,13 @@ generateByrefDisposeHelper(CodeGenFunction &CGF,
IdentifierInfo *II
= &Context.Idents.get("__Block_byref_object_dispose_");
FunctionDecl *FD = FunctionDecl::Create(Context,
Context.getTranslationUnitDecl(),
SourceLocation(),
SourceLocation(), II, R, nullptr,
SC_Static,
false, false);
SmallVector<QualType, 1> ArgTys;
ArgTys.push_back(Context.VoidPtrTy);
QualType FunctionTy = Context.getFunctionType(R, ArgTys, {});
FunctionDecl *FD = FunctionDecl::Create(
Context, Context.getTranslationUnitDecl(), SourceLocation(),
SourceLocation(), II, FunctionTy, nullptr, SC_Static, false, false);
CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);

View File

@ -1068,30 +1068,37 @@ llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction(
if (llvm::Function *F = CGM.getModule().getFunction(Name))
return F;
llvm::SmallVector<QualType, 4> ArgTys;
llvm::SmallVector<ImplicitParamDecl, 4> Params;
Params.emplace_back(Ctx, nullptr, SourceLocation(), &Ctx.Idents.get("buffer"),
Ctx.VoidPtrTy, ImplicitParamDecl::Other);
ArgTys.emplace_back(Ctx.VoidPtrTy);
for (unsigned int I = 0, E = Layout.Items.size(); I < E; ++I) {
char Size = Layout.Items[I].getSizeByte();
if (!Size)
continue;
QualType ArgTy = getOSLogArgType(Ctx, Size);
Params.emplace_back(
Ctx, nullptr, SourceLocation(),
&Ctx.Idents.get(std::string("arg") + llvm::to_string(I)),
getOSLogArgType(Ctx, Size), ImplicitParamDecl::Other);
&Ctx.Idents.get(std::string("arg") + llvm::to_string(I)), ArgTy,
ImplicitParamDecl::Other);
ArgTys.emplace_back(ArgTy);
}
FunctionArgList Args;
for (auto &P : Params)
Args.push_back(&P);
QualType ReturnTy = Ctx.VoidTy;
QualType FuncionTy = Ctx.getFunctionType(ReturnTy, ArgTys, {});
// The helper function has linkonce_odr linkage to enable the linker to merge
// identical functions. To ensure the merging always happens, 'noinline' is
// attached to the function when compiling with -Oz.
const CGFunctionInfo &FI =
CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, Args);
llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
llvm::Function *Fn = llvm::Function::Create(
FuncTy, llvm::GlobalValue::LinkOnceODRLinkage, Name, &CGM.getModule());
@ -1107,9 +1114,9 @@ llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction(
IdentifierInfo *II = &Ctx.Idents.get(Name);
FunctionDecl *FD = FunctionDecl::Create(
Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
Ctx.VoidTy, nullptr, SC_PrivateExtern, false, false);
FuncionTy, nullptr, SC_PrivateExtern, false, false);
StartFunction(FD, Ctx.VoidTy, Fn, FI, Args);
StartFunction(FD, ReturnTy, Fn, FI, Args);
// Create a scope with an artificial location for the body of this function.
auto AL = ApplyDebugLocation::CreateArtificial(*this);

View File

@ -463,7 +463,8 @@ template <class Derived> struct GenFuncBase {
IdentifierInfo *II = &Ctx.Idents.get(FuncName);
FunctionDecl *FD = FunctionDecl::Create(
Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
II, Ctx.VoidTy, nullptr, SC_PrivateExtern, false, false);
II, Ctx.getFunctionType(Ctx.VoidTy, llvm::None, {}), nullptr,
SC_PrivateExtern, false, false);
CodeGenFunction NewCGF(CGM);
setCGF(&NewCGF);
CGF->StartFunction(FD, Ctx.VoidTy, F, FI, Args);

View File

@ -3249,29 +3249,32 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
ASTContext &C = getContext();
IdentifierInfo *II
= &CGM.getContext().Idents.get("__assign_helper_atomic_property_");
FunctionDecl *FD = FunctionDecl::Create(C,
C.getTranslationUnitDecl(),
SourceLocation(),
SourceLocation(), II, C.VoidTy,
nullptr, SC_Static,
false,
false);
QualType ReturnTy = C.VoidTy;
QualType DestTy = C.getPointerType(Ty);
QualType SrcTy = Ty;
SrcTy.addConst();
SrcTy = C.getPointerType(SrcTy);
SmallVector<QualType, 2> ArgTys;
ArgTys.push_back(DestTy);
ArgTys.push_back(SrcTy);
QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
FunctionDecl *FD = FunctionDecl::Create(
C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
FunctionTy, nullptr, SC_Static, false, false);
FunctionArgList args;
ImplicitParamDecl DstDecl(getContext(), FD, SourceLocation(), /*Id=*/nullptr,
DestTy, ImplicitParamDecl::Other);
ImplicitParamDecl DstDecl(C, FD, SourceLocation(), /*Id=*/nullptr, DestTy,
ImplicitParamDecl::Other);
args.push_back(&DstDecl);
ImplicitParamDecl SrcDecl(getContext(), FD, SourceLocation(), /*Id=*/nullptr,
SrcTy, ImplicitParamDecl::Other);
ImplicitParamDecl SrcDecl(C, FD, SourceLocation(), /*Id=*/nullptr, SrcTy,
ImplicitParamDecl::Other);
args.push_back(&SrcDecl);
const CGFunctionInfo &FI =
CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args);
CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);
llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
@ -3282,7 +3285,7 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
StartFunction(FD, C.VoidTy, Fn, FI, args);
StartFunction(FD, ReturnTy, Fn, FI, args);
DeclRefExpr DstExpr(&DstDecl, false, DestTy,
VK_RValue, SourceLocation());
@ -3321,50 +3324,51 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(
if ((!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic)))
return nullptr;
llvm::Constant *HelperFn = nullptr;
if (hasTrivialGetExpr(PID))
return nullptr;
assert(PID->getGetterCXXConstructor() && "getGetterCXXConstructor - null");
if ((HelperFn = CGM.getAtomicGetterHelperFnMap(Ty)))
return HelperFn;
ASTContext &C = getContext();
IdentifierInfo *II
= &CGM.getContext().Idents.get("__copy_helper_atomic_property_");
FunctionDecl *FD = FunctionDecl::Create(C,
C.getTranslationUnitDecl(),
SourceLocation(),
SourceLocation(), II, C.VoidTy,
nullptr, SC_Static,
false,
false);
IdentifierInfo *II =
&CGM.getContext().Idents.get("__copy_helper_atomic_property_");
QualType ReturnTy = C.VoidTy;
QualType DestTy = C.getPointerType(Ty);
QualType SrcTy = Ty;
SrcTy.addConst();
SrcTy = C.getPointerType(SrcTy);
SmallVector<QualType, 2> ArgTys;
ArgTys.push_back(DestTy);
ArgTys.push_back(SrcTy);
QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
FunctionDecl *FD = FunctionDecl::Create(
C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
FunctionTy, nullptr, SC_Static, false, false);
FunctionArgList args;
ImplicitParamDecl DstDecl(getContext(), FD, SourceLocation(), /*Id=*/nullptr,
DestTy, ImplicitParamDecl::Other);
ImplicitParamDecl DstDecl(C, FD, SourceLocation(), /*Id=*/nullptr, DestTy,
ImplicitParamDecl::Other);
args.push_back(&DstDecl);
ImplicitParamDecl SrcDecl(getContext(), FD, SourceLocation(), /*Id=*/nullptr,
SrcTy, ImplicitParamDecl::Other);
ImplicitParamDecl SrcDecl(C, FD, SourceLocation(), /*Id=*/nullptr, SrcTy,
ImplicitParamDecl::Other);
args.push_back(&SrcDecl);
const CGFunctionInfo &FI =
CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args);
CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);
llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
llvm::Function *Fn =
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
"__copy_helper_atomic_property_", &CGM.getModule());
llvm::Function *Fn = llvm::Function::Create(
LTy, llvm::GlobalValue::InternalLinkage, "__copy_helper_atomic_property_",
&CGM.getModule());
CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
StartFunction(FD, C.VoidTy, Fn, FI, args);
StartFunction(FD, ReturnTy, Fn, FI, args);
DeclRefExpr SrcExpr(&SrcDecl, false, SrcTy,
VK_RValue, SourceLocation());

View File

@ -385,12 +385,12 @@ static llvm::Function *emitOutlinedFunctionPrologue(
FunctionDecl *DebugFunctionDecl = nullptr;
if (!FO.UIntPtrCastRequired) {
FunctionProtoType::ExtProtoInfo EPI;
QualType FunctionTy = Ctx.getFunctionType(Ctx.VoidTy, llvm::None, EPI);
DebugFunctionDecl = FunctionDecl::Create(
Ctx, Ctx.getTranslationUnitDecl(), FO.S->getBeginLoc(),
SourceLocation(), DeclarationName(), Ctx.VoidTy,
Ctx.getTrivialTypeSourceInfo(
Ctx.getFunctionType(Ctx.VoidTy, llvm::None, EPI)),
SC_Static, /*isInlineSpecified=*/false, /*hasWrittenPrototype=*/false);
SourceLocation(), DeclarationName(), FunctionTy,
Ctx.getTrivialTypeSourceInfo(FunctionTy), SC_Static,
/*isInlineSpecified=*/false, /*hasWrittenPrototype=*/false);
}
for (const FieldDecl *FD : RD->fields()) {
QualType ArgType = FD->getType();

View File

@ -2315,11 +2315,13 @@ void CodeGenModule::registerGlobalDtorsWithAtExit() {
FTy, GlobalInitFnName, getTypes().arrangeNullaryFunction(),
SourceLocation());
ASTContext &Ctx = getContext();
QualType ReturnTy = Ctx.VoidTy;
QualType FunctionTy = Ctx.getFunctionType(ReturnTy, llvm::None, {});
FunctionDecl *FD = FunctionDecl::Create(
Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
&Ctx.Idents.get(GlobalInitFnName), Ctx.VoidTy, nullptr, SC_Static,
&Ctx.Idents.get(GlobalInitFnName), FunctionTy, nullptr, SC_Static,
false, false);
CGF.StartFunction(GlobalDecl(FD), getContext().VoidTy, GlobalInitFn,
CGF.StartFunction(GlobalDecl(FD), ReturnTy, GlobalInitFn,
getTypes().arrangeNullaryFunction(), FunctionArgList(),
SourceLocation(), SourceLocation());

View File

@ -3099,10 +3099,9 @@ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFla
SmallVectorImpl<Expr*> &MsgExprs,
ObjCMethodDecl *Method) {
// Now do the "normal" pointer to function cast.
QualType castType = getSimpleFunctionType(returnType, ArgTypes,
Method ? Method->isVariadic()
: false);
castType = Context->getPointerType(castType);
QualType FuncType = getSimpleFunctionType(
returnType, ArgTypes, Method ? Method->isVariadic() : false);
QualType castType = Context->getPointerType(FuncType);
// build type for containing the objc_msgSend_stret object.
static unsigned stretCount=0;
@ -3176,9 +3175,9 @@ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFla
// AST for __Stretn(receiver, args).s;
IdentifierInfo *ID = &Context->Idents.get(name);
FunctionDecl *FD = FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
SourceLocation(), ID, castType,
nullptr, SC_Extern, false, false);
FunctionDecl *FD =
FunctionDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(),
ID, FuncType, nullptr, SC_Extern, false, false);
DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, castType, VK_RValue,
SourceLocation());
CallExpr *STCE = new (Context) CallExpr(*Context, DRE, MsgExprs,

View File

@ -0,0 +1,9 @@
// RUN: %clang_cc1 -fblocks -fsanitize=function -emit-llvm %s -o %t
void g(void (^)());
void f() {
__block int a = 0;
g(^() {
a++;
});
}