[cfe-dev] Performing a path-sensitive check only when a function return value is ignored
McDowell, Raymond C. via cfe-dev
cfe-dev at lists.llvm.org
Tue Jun 21 14:25:11 PDT 2016
I generally followed Artem's suggestions (for my approach) and things worked out okay. Specifically:
void MyChecker::checkPreCall(const CallEvent &Call, CheckerContext &ChCtx) const {
const Stmt *Parent = ChCtx.getStackFrame()->getParentMap().getParent(Call.getOriginExpr());
if (!Parent || !isa<CompoundStmt>(Parent))
return;
// Proceed with my checks.
}
Then I generalized this a bit, but still in a syntactic way (not in the path-sensitive way Artem suggested). The idea is to follow the parent chain to get the first non-Expr statement containing the call, and then check if that statement makes use of the expression value (which is built from the call's return value).
bool isReturnValueUsed(const CallEvent &Call, CheckerContext &ChCtx) {
const ParentMap &PM = ChCtx.getStackFrame()->getParentMap();
const Expr *TopLevelExpr = Call.getOriginExpr();
const Stmt *Containing Stmt = PM.getParent(TopLevelExpr);
while (ContainingStmt && isa<Expr>(ContainingStmt)) {
if (is<BinaryOperator>(ContainingStmt) && cast<BinaryOperator>(ContainingStmt)->isAssignmentOp())
return true; // return value is used in an assignment
TopLevelExpr = cast<Expr>(ContainingStmt);
ContainingStmt = PM.getParent(TopLevelExpr);
}
if (!ContainingStmt)
return false;
if (isa<DeclStmt>(ContainingStmt))
return true; // return value is used in an initialization
if (isa<IfStmt>(ContainingStmt) && TopLevelExpr == cast<IfStmt>(ContainingStmt)->getCond())
return true; // return value is used in an if condition
if (isa<SwitchStmt>(ContainingStmt) && TopLevelExpr == cast<SwitchStmt>(ContainingStmt)->getCond())
return true; // return value is used in a switch condition
if (isa<WhileStmt>(ContainingStmt) && TopLevelExpr == cast<WhileStmt>(ContainingStmt)->getCond())
return true; // return value is used in a while loop condition
if (isa<DoStmt>(ContainingStmt) && TopLevelExpr == cast<DoStmt>(ContainingStmt)->getCond())
return true; // return value is used in do loop condition
if (isa<ReturnStmt>(ContainingStmt) && TopLevelExpr == cast<ReturnStmt>(ContainingStmt)->getRetValue())
return true; // return value is used to construct a higher-level return value
return false;
}
void MyChecker::checkPreCall(const CallEvent &Call, CheckerContext &ChCtx) const {
const Stmt *Parent = ChCtx.getStackFrame()->getParentMap().getParent(Call.getOriginExpr());
if (!Parent || !isa<CompoundStmt>(Parent))
return;
// Proceed with my checks.
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160621/71a82a7d/attachment.html>
More information about the cfe-dev
mailing list