Author: george.karpenkov Date: Tue May 15 17:29:13 2018 New Revision: 332422
URL: http://llvm.org/viewvc/llvm-project?rev=332422&view=rev Log: [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 Modified: cfe/trunk/lib/Analysis/BodyFarm.cpp cfe/trunk/test/Analysis/call_once.cpp Modified: cfe/trunk/lib/Analysis/BodyFarm.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BodyFarm.cpp?rev=332422&r1=332421&r2=332422&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/BodyFarm.cpp (original) +++ cfe/trunk/lib/Analysis/BodyFarm.cpp Tue May 15 17:29:13 2018 @@ -254,21 +254,24 @@ static CallExpr *create_call_once_funcpt 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, Modified: cfe/trunk/test/Analysis/call_once.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/call_once.cpp?rev=332422&r1=332421&r2=332422&view=diff ============================================================================== --- cfe/trunk/test/Analysis/call_once.cpp (original) +++ cfe/trunk/test/Analysis/call_once.cpp Tue May 15 17:29:13 2018 @@ -403,3 +403,12 @@ void callback_with_implicit_cast() { std::once_flag flag; call_once(flag, callback_taking_func, callback_with_implicit_cast); } + +std::once_flag another_once_flag; +typedef void (*my_callback_t)(int *); +my_callback_t callback; +int global_int; + +void rdar40270582() { + call_once(another_once_flag, callback, &global_int); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits