diff options
author | George Karpenkov <ekarpenkov@apple.com> | 2017-10-24 00:13:18 +0000 |
---|---|---|
committer | George Karpenkov <ekarpenkov@apple.com> | 2017-10-24 00:13:18 +0000 |
commit | 68518a40c274d4ee6ecad035363ac6a1040b617f (patch) | |
tree | 5a37a10e81dd376ec2fdf41868aa8c7df10bb0a3 /lib/Analysis/BodyFarm.cpp | |
parent | 2b1d1f02e9ceb837f16cf85447f8211f331954b1 (diff) | |
download | clang-68518a40c274d4ee6ecad035363ac6a1040b617f.tar.gz |
[Analyzer] Handle implicit function reference in bodyfarming std::call_once
Differential Revision: https://reviews.llvm.org/D39201
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316402 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/BodyFarm.cpp')
-rw-r--r-- | lib/Analysis/BodyFarm.cpp | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp index dd348847b3..8a56b761ec 100644 --- a/lib/Analysis/BodyFarm.cpp +++ b/lib/Analysis/BodyFarm.cpp @@ -253,13 +253,23 @@ static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M, const ParmVarDecl *Callback, ArrayRef<Expr *> CallArgs) { - return new (C) CallExpr( - /*ASTContext=*/C, - /*StmtClass=*/M.makeLvalueToRvalue(/*Expr=*/Callback), - /*args=*/CallArgs, - /*QualType=*/C.VoidTy, - /*ExprValueType=*/VK_RValue, - /*SourceLocation=*/SourceLocation()); + QualType Ty = Callback->getType(); + DeclRefExpr *Call = M.makeDeclRefExpr(Callback); + CastKind CK; + if (Ty->isRValueReferenceType()) { + CK = CK_LValueToRValue; + } else { + assert(Ty->isLValueReferenceType()); + CK = CK_FunctionToPointerDecay; + Ty = C.getPointerType(Ty.getNonReferenceType()); + } + + return new (C) + CallExpr(C, M.makeImplicitCast(Call, Ty.getNonReferenceType(), CK), + /*args=*/CallArgs, + /*QualType=*/C.VoidTy, + /*ExprValueType=*/VK_RValue, + /*SourceLocation=*/SourceLocation()); } static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M, @@ -366,9 +376,11 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { CallbackFunctionType = CallbackRecordDecl->getLambdaCallOperator() ->getType() ->getAs<FunctionProtoType>(); - } else { + } else if (!CallbackType->getPointeeType().isNull()) { CallbackFunctionType = CallbackType->getPointeeType()->getAs<FunctionProtoType>(); + } else { + CallbackFunctionType = CallbackType->getAs<FunctionProtoType>(); } if (!CallbackFunctionType) |