aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/Consumed.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis/Consumed.cpp')
-rw-r--r--clang/lib/Analysis/Consumed.cpp43
1 files changed, 23 insertions, 20 deletions
diff --git a/clang/lib/Analysis/Consumed.cpp b/clang/lib/Analysis/Consumed.cpp
index cde753e..c277177 100644
--- a/clang/lib/Analysis/Consumed.cpp
+++ b/clang/lib/Analysis/Consumed.cpp
@@ -494,8 +494,10 @@ public:
void checkCallability(const PropagationInfo &PInfo,
const FunctionDecl *FunDecl,
SourceLocation BlameLoc);
- bool handleCall(const CallExpr *Call, const Expr *ObjArg,
- const FunctionDecl *FunD);
+
+ using ArgRange = llvm::iterator_range<CallExpr::const_arg_iterator>;
+ bool handleCall(const Expr *Call, const Expr *ObjArg,
+ ArgRange args, const FunctionDecl *FunD);
void VisitBinaryOperator(const BinaryOperator *BinOp);
void VisitCallExpr(const CallExpr *Call);
@@ -608,22 +610,21 @@ void ConsumedStmtVisitor::checkCallability(const PropagationInfo &PInfo,
// Factors out common behavior for function, method, and operator calls.
// Check parameters and set parameter state if necessary.
// Returns true if the state of ObjArg is set, or false otherwise.
-bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg,
+bool ConsumedStmtVisitor::handleCall(const Expr *Call,
+ const Expr *ObjArg,
+ ArgRange Args,
const FunctionDecl *FunD) {
- unsigned Offset = 0;
- if (isa<CXXOperatorCallExpr>(Call) && isa<CXXMethodDecl>(FunD))
- Offset = 1; // first argument is 'this'
-
// check explicit parameters
- for (unsigned Index = Offset; Index < Call->getNumArgs(); ++Index) {
+ unsigned Index = 0;
+ for (const Expr *Arg : Args) {
// Skip variable argument lists.
- if (Index - Offset >= FunD->getNumParams())
+ if (Index >= FunD->getNumParams())
break;
- const ParmVarDecl *Param = FunD->getParamDecl(Index - Offset);
+ const ParmVarDecl *Param = FunD->getParamDecl(Index++);
QualType ParamType = Param->getType();
- InfoEntry Entry = findInfo(Call->getArg(Index));
+ InfoEntry Entry = findInfo(Arg);
if (Entry == PropagationMap.end() || Entry->second.isTest())
continue;
@@ -636,7 +637,7 @@ bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg,
if (ParamState != ExpectedState)
Analyzer.WarningsHandler.warnParamTypestateMismatch(
- Call->getArg(Index)->getExprLoc(),
+ Arg->getExprLoc(),
stateToString(ExpectedState), stateToString(ParamState));
}
@@ -749,7 +750,7 @@ void ConsumedStmtVisitor::VisitCallExpr(const CallExpr *Call) {
return;
}
- handleCall(Call, nullptr, FunDecl);
+ handleCall(Call, nullptr, Call->arguments(), FunDecl);
propagateReturnType(Call, FunDecl);
}
@@ -805,7 +806,7 @@ void ConsumedStmtVisitor::VisitCXXMemberCallExpr(
if (!MD)
return;
- handleCall(Call, Call->getImplicitObjectArgument(), MD);
+ handleCall(Call, Call->getImplicitObjectArgument(), Call->arguments(), MD);
propagateReturnType(Call, MD);
}
@@ -813,18 +814,20 @@ void ConsumedStmtVisitor::VisitCXXOperatorCallExpr(
const CXXOperatorCallExpr *Call) {
const auto *FunDecl = dyn_cast_or_null<FunctionDecl>(Call->getDirectCallee());
if (!FunDecl) return;
+ ArgRange Args = Call->arguments();
if (Call->getOperator() == OO_Equal) {
- ConsumedState CS = getInfo(Call->getArg(1));
- if (!handleCall(Call, Call->getArg(0), FunDecl))
- setInfo(Call->getArg(0), CS);
+ ConsumedState CS = getInfo(llvm::index(Args, 1));
+ if (!handleCall(Call, llvm::index(Args, 0), llvm::drop_begin(Args, 1),
+ FunDecl))
+ setInfo(llvm::index(Args, 0), CS);
return;
}
- if (const auto *MCall = dyn_cast<CXXMemberCallExpr>(Call))
- handleCall(MCall, MCall->getImplicitObjectArgument(), FunDecl);
+ if (isa<CXXMethodDecl>(FunDecl))
+ handleCall(Call, llvm::index(Args, 0), llvm::drop_begin(Args, 1), FunDecl);
else
- handleCall(Call, Call->getArg(0), FunDecl);
+ handleCall(Call, nullptr, Args, FunDecl);
propagateReturnType(Call, FunDecl);
}