[PATCH] D72705: [analyzer] Added new checker 'alpha.unix.ErrorReturn'.
Kristóf Umann via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 24 09:09:44 PDT 2020
Szelethus added inline comments.
================
Comment at: clang/lib/StaticAnalyzer/Checkers/ErrorReturnChecker.cpp:309-311
+void ErrorReturnChecker::checkAccess(CheckerContext &C, ProgramStateRef State,
+ const Stmt *LoadS, SymbolRef CallSym,
+ const CalledFunctionData *CFD) const {
----------------
NoQ wrote:
> Why scan parent statements proactively given that we will reach them later anyway? Looks like you're using a wrong checker callback.
Thats one of the things I'm not super familiar with just yet. Are you referencing how a CFGBlock is built up? I remember trying to solve a similar problem (dig writes/reads out of `Stmt *`s) when working on the reaching definitions calculator, and I question my methodology as well.
test.cpp:
```lang=c++
int getInt();
void different_assignments() {
int i = getInt(); // Return value to check.
if (static_cast<bool>(i < 7))
;
}
```
AST:
```
`-FunctionDecl 0xaf6ff0 <line:3:1, line:8:1> line:3:6 different_assignments 'void ()'
`-CompoundStmt 0xaf72d8 <col:30, line:8:1>
|-DeclStmt 0xaf71e8 <line:4:3, col:19>
| `-VarDecl 0xaf70a8 <col:3, col:18> col:7 used i 'int' cinit
| `-CallExpr 0xaf71c8 <col:11, col:18> 'int'
| `-ImplicitCastExpr 0xaf71b0 <col:11> 'int (*)()' <FunctionToPointerDecay>
| `-DeclRefExpr 0xaf7158 <col:11> 'int ()' lvalue Function 0xaf6eb8 'getInt' 'int ()'
`-IfStmt 0xaf72c0 <line:6:3, line:7:5>
|-CXXStaticCastExpr 0xaf7288 <line:6:7, col:30> 'bool' static_cast<_Bool> <NoOp>
| `-BinaryOperator 0xaf7258 <col:25, col:29> 'bool' '<'
| |-ImplicitCastExpr 0xaf7240 <col:25> 'int' <LValueToRValue>
| | `-DeclRefExpr 0xaf7200 <col:25> 'int' lvalue Var 0xaf70a8 'i' 'int'
| `-IntegerLiteral 0xaf7220 <col:29> 'int' 7
`-NullStmt 0xaf72b8 <line:7:5>
```
CFG:
```
void different_assignments()
[B3 (ENTRY)]
Succs (1): B2
[B1]
Preds (1): B2
Succs (1): B0
[B2]
1: getInt
2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, int (*)(void))
3: [B2.2]()
4: int i = getInt();
5: i
6: [B2.5] (ImplicitCastExpr, LValueToRValue, int)
7: 7
8: [B2.6] < [B2.7]
9: static_cast<bool>([B2.8]) (CXXStaticCastExpr, NoOp, _Bool)
T: if [B2.9]
Preds (1): B3
Succs (2): B1 B0
[B0 (EXIT)]
Preds (2): B1 B2
```
I can see that a single statement has multiple CFGElements associated with it (implying that multiple checker callbacks might be invoked). Is your point tat we shouldn't do all the analysis at Block 2 CFGElement 6, but rather at Block 2 Element 9?
As I see this checker, what we want at the end of the day is to see a critical return value (say `ptr`) or **a derived value of it** (say `(ptr != nullptr && someOtherPrecondition()`) in a branch condition. But I think working from `checkBranchCondition` and working down the AST (does `ptr` or some other return value participate in this condition?) , as opposed to using `checkLoation` and working working up (is `ptr`'s read here a part of a condition?) doesn't immediately feel like an easier, shorter or less error-prone solution.
A random idea, what we could try out is to store accesses to return values in `checkLocation` in the GDM, and check in `checkBranchCondition` whether its a substatement.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D72705/new/
https://reviews.llvm.org/D72705
More information about the cfe-commits
mailing list