It makes sense to track rvalue expressions in the case of special
concrete integer values. The most notable special value is zero (later
we may find other values). By tracking the origin of 0, we can provide a
better explanation for users e.g. in case of division by 0 warnings.
When the divisor is a product of a multiplication then now we can show
which operand (or both) was (were) zero and why.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
I really like it. Looks good.
I'm letting someone else accept this as I've not really touched the trackExpression parts.
clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h | ||
---|---|---|
119–124 | It is supposed to be called by the trackExpressionValue(). |
clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h | ||
---|---|---|
119–124 | I was thinking about that maybe some Checkers could explicitly want to track RValues only. On the other hand, maybe it just complicates the public API. Anyway, I'd like to hear what other people say about this. |
I think this is a good targeted fix for that problem we've discussed, demonstrated by tests.
clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h | ||
---|---|---|
119–124 | I suggest keep it private until there's an actual use case. As of now literally nobody understands how these functions are even supposed to work so it's way too early to give API promises. | |
clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | ||
1945 | SVal::isZeroConstant() please ^.^ |
- Use isZeroConstant()
- Make trackRValueExpression private (static function)
- Fix clang-tidy report: auto *BO ---> const auto *BO
Guys, thanks for the review! :)
clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | ||
---|---|---|
1945 | Yeah good catch, I wish I knew this before :) |
Some minor logical issues inline.
clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | ||
---|---|---|
1944–1945 | There are only 3 multiplicative operators: BINARY_OPERATION(Mul, "*") BINARY_OPERATION(Div, "/") BINARY_OPERATION(Rem, "%") So, the opcode can never be BO_MulAssign later. |
clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | ||
---|---|---|
1944–1945 | Yep, good catch! The reason why the assignment test case passed is that we already handle assignment operations in the FindLastStoreBRVisitor. // If this is an assignment expression, we can track the value // being assigned. if (Optional<PostStmt> P = Succ->getLocationAs<PostStmt>()) if (const BinaryOperator *BO = P->getStmtAs<BinaryOperator>()) if (BO->isAssignmentOp()) InitE = BO->getRHS(); So, I could just remove the handling of the assignment from the new function. |
clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | ||
---|---|---|
1958–1959 | Both divisions and modulo operations can flow here. |
clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | ||
---|---|---|
1958–1959 | Ok, I updated the comment. |
land it
clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | ||
---|---|---|
1938 | This note is not strictly for this patch. At first, it wasn't clear to me why you call getSValAsScalarOrLoc(). |
It is supposed to be called by the trackExpressionValue().
Why do we expose this function then?