summaryrefslogtreecommitdiff
path: root/lib/Analysis/BodyFarm.cpp
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2017-10-24 00:13:18 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2017-10-24 00:13:18 +0000
commit68518a40c274d4ee6ecad035363ac6a1040b617f (patch)
tree5a37a10e81dd376ec2fdf41868aa8c7df10bb0a3 /lib/Analysis/BodyFarm.cpp
parent2b1d1f02e9ceb837f16cf85447f8211f331954b1 (diff)
downloadclang-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.cpp28
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)