From: George Karpenkov Date: Mon, 2 Oct 2017 21:01:46 +0000 (+0000) Subject: [Analyzer] Avoid copy and modifying passed reference in BodyFarm::create_call_once X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3c43204d0b2175212bb4cd9930094d40b69ecf72;p=clang [Analyzer] Avoid copy and modifying passed reference in BodyFarm::create_call_once Differential Revision: https://reviews.llvm.org/D38475 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@314722 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp index acab7c5e91..a6597690c2 100644 --- a/lib/Analysis/BodyFarm.cpp +++ b/lib/Analysis/BodyFarm.cpp @@ -257,10 +257,9 @@ NamedDecl *ASTMaker::findMemberField(const CXXRecordDecl *RD, StringRef Name) { typedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D); -static CallExpr * -create_call_once_funcptr_call(ASTContext &C, ASTMaker M, - const ParmVarDecl *Callback, - SmallVectorImpl &CallArgs) { +static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M, + const ParmVarDecl *Callback, + ArrayRef CallArgs) { return new (C) CallExpr( /*ASTContext=*/C, @@ -271,10 +270,10 @@ create_call_once_funcptr_call(ASTContext &C, ASTMaker M, /*SourceLocation=*/SourceLocation()); } -static CallExpr * -create_call_once_lambda_call(ASTContext &C, ASTMaker M, - const ParmVarDecl *Callback, QualType CallbackType, - SmallVectorImpl &CallArgs) { +static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M, + const ParmVarDecl *Callback, + QualType CallbackType, + ArrayRef CallArgs) { CXXRecordDecl *CallbackDecl = CallbackType->getAsCXXRecordDecl(); @@ -293,12 +292,6 @@ create_call_once_lambda_call(ASTContext &C, ASTMaker M, /* T = */ callOperatorDecl->getType(), /* VK = */ VK_LValue); - CallArgs.insert( - CallArgs.begin(), - M.makeDeclRefExpr(Callback, - /* RefersToEnclosingVariableOrCapture= */ true, - /* GetNonReferenceType= */ true)); - return new (C) CXXOperatorCallExpr(/*AstContext=*/C, OO_Call, callOperatorDeclRef, /*args=*/CallArgs, @@ -335,15 +328,24 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { const ParmVarDecl *Callback = D->getParamDecl(1); QualType CallbackType = Callback->getType().getNonReferenceType(); + bool isLambdaCall = CallbackType->getAsCXXRecordDecl() && + CallbackType->getAsCXXRecordDecl()->isLambda(); + SmallVector CallArgs; + if (isLambdaCall) + // Lambda requires callback itself inserted as a first parameter. + CallArgs.push_back( + M.makeDeclRefExpr(Callback, + /* RefersToEnclosingVariableOrCapture= */ true, + /* GetNonReferenceType= */ true)); + // All arguments past first two ones are passed to the callback. for (unsigned int i = 2; i < D->getNumParams(); i++) CallArgs.push_back(M.makeLvalueToRvalue(D->getParamDecl(i))); CallExpr *CallbackCall; - if (CallbackType->getAsCXXRecordDecl() && - CallbackType->getAsCXXRecordDecl()->isLambda()) { + if (isLambdaCall) { CallbackCall = create_call_once_lambda_call(C, M, Callback, CallbackType, CallArgs);