[Analyzer] Avoid copy and modifying passed reference in BodyFarm::create_call_once

Differential Revision: https://reviews.llvm.org/D38475

llvm-svn: 314722
This commit is contained in:
George Karpenkov 2017-10-02 21:01:46 +00:00
parent c6004d0371
commit 6dda6712cc
1 changed files with 18 additions and 16 deletions

View File

@ -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<Expr *> &CallArgs) {
static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M,
const ParmVarDecl *Callback,
ArrayRef<Expr *> 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<Expr *> &CallArgs) {
static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
const ParmVarDecl *Callback,
QualType CallbackType,
ArrayRef<Expr *> 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<Expr *, 5> 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);