From faa03f4acaf5a7a2654c440f590c0ba31242b482 Mon Sep 17 00:00:00 2001 From: George Karpenkov Date: Wed, 16 May 2018 00:29:13 +0000 Subject: [analyzer] Do not crash on callback for call_once passed by value https://bugs.llvm.org/show_bug.cgi?id=37312 rdar://40270582 Differential Revision: https://reviews.llvm.org/D46913 llvm-svn: 332422 --- clang/lib/Analysis/BodyFarm.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'clang/lib/Analysis') diff --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp index 61aa2e3e4ac..b9fb15b2db2 100644 --- a/clang/lib/Analysis/BodyFarm.cpp +++ b/clang/lib/Analysis/BodyFarm.cpp @@ -254,21 +254,24 @@ static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M, QualType Ty = Callback->getType(); DeclRefExpr *Call = M.makeDeclRefExpr(Callback); - CastKind CK; + Expr *SubExpr; if (Ty->isRValueReferenceType()) { - CK = CK_LValueToRValue; - } else { - assert(Ty->isLValueReferenceType()); - CK = CK_FunctionToPointerDecay; + SubExpr = M.makeImplicitCast( + Call, Ty.getNonReferenceType(), CK_LValueToRValue); + } else if (Ty->isLValueReferenceType() && + Call->getType()->isFunctionType()) { Ty = C.getPointerType(Ty.getNonReferenceType()); + SubExpr = M.makeImplicitCast(Call, Ty, CK_FunctionToPointerDecay); + } else if (Ty->isLValueReferenceType() + && Call->getType()->isPointerType() + && Call->getType()->getPointeeType()->isFunctionType()){ + SubExpr = Call; + } else { + llvm_unreachable("Unexpected state"); } return new (C) - CallExpr(C, M.makeImplicitCast(Call, Ty.getNonReferenceType(), CK), - /*args=*/CallArgs, - /*QualType=*/C.VoidTy, - /*ExprValueType=*/VK_RValue, - /*SourceLocation=*/SourceLocation()); + CallExpr(C, SubExpr, CallArgs, C.VoidTy, VK_RValue, SourceLocation()); } static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M, -- cgit v1.2.3