baloghadamsoftware updated this revision to Diff 247910.
baloghadamsoftware added a comment.
Alternative approach for debugging (instead of checking the source range):
`clang_analyzer_express()` from `ExprInspection` marks its argument as
interesting in the bug report. `DebugContainerModeling` propagates the
interestingness from the symbol (begin or end symbol of the container) to the
container itself.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D75514/new/
https://reviews.llvm.org/D75514
Files:
clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
clang/test/Analysis/container-modeling.cpp
Index: clang/test/Analysis/container-modeling.cpp
===================================================================
--- clang/test/Analysis/container-modeling.cpp
+++ clang/test/Analysis/container-modeling.cpp
@@ -208,7 +208,7 @@
clang_analyzer_denote(clang_analyzer_container_begin(V1), "$V1.begin()");
- V2.push_back(n); // expected-note{{Container 'V2' extended to the right by 1 position}} FIXME: This note should not appear since `V2` is not affected in the "bug"
+ V2.push_back(n); // no note expected
clang_analyzer_express(clang_analyzer_container_begin(V1)); // expected-warning{{$V1.begin()}}
// expected-note@-1{{$V1.begin()}}
@@ -223,8 +223,7 @@
clang_analyzer_denote(clang_analyzer_container_begin(V1), "$V1.begin()");
clang_analyzer_denote(clang_analyzer_container_begin(V2), "$V2.begin()");
- V1.push_back(n); // expected-note{{Container 'V1' extended to the right by 1 position}}
- // expected-note@-1{{Container 'V1' extended to the right by 1 position}} FIXME: This should appear only once since there is only one "bug" where `V1` is affected
+ V1.push_back(n); // expected-note{{Container 'V1' extended to the right by 1 position}} -- Only once!
clang_analyzer_express(clang_analyzer_container_begin(V1)); // expected-warning{{$V1.begin()}}
// expected-note@-1{{$V1.begin()}}
Index: clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -50,9 +50,11 @@
typedef void (ExprInspectionChecker::*FnCheck)(const CallExpr *,
CheckerContext &C) const;
- ExplodedNode *reportBug(llvm::StringRef Msg, CheckerContext &C) const;
+ ExplodedNode *reportBug(llvm::StringRef Msg, CheckerContext &C,
+ SVal ExprVal = UndefinedVal()) const;
ExplodedNode *reportBug(llvm::StringRef Msg, BugReporter &BR,
- ExplodedNode *N) const;
+ ExplodedNode *N,
+ SVal ExprVal = UndefinedVal()) const;
public:
bool evalCall(const CallEvent &Call, CheckerContext &C) const;
@@ -134,22 +136,28 @@
}
ExplodedNode *ExprInspectionChecker::reportBug(llvm::StringRef Msg,
- CheckerContext &C) const {
+ CheckerContext &C,
+ SVal ExprVal) const {
ExplodedNode *N = C.generateNonFatalErrorNode();
- reportBug(Msg, C.getBugReporter(), N);
+ reportBug(Msg, C.getBugReporter(), N, ExprVal);
return N;
}
ExplodedNode *ExprInspectionChecker::reportBug(llvm::StringRef Msg,
BugReporter &BR,
- ExplodedNode *N) const {
+ ExplodedNode *N,
+ SVal ExprVal) const {
if (!N)
return nullptr;
if (!BT)
BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
- BR.emitReport(std::make_unique<PathSensitiveBugReport>(*BT, Msg, N));
+ auto R = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
+ if (!ExprVal.isUndef()) {
+ R->markInteresting(ExprVal);
+ }
+ BR.emitReport(std::move(R));
return N;
}
@@ -396,7 +404,8 @@
return;
}
- SymbolRef Sym = C.getSVal(CE->getArg(0)).getAsSymbol();
+ SVal ArgVal = C.getSVal(CE->getArg(0));
+ SymbolRef Sym = ArgVal.getAsSymbol();
if (!Sym) {
reportBug("Not a symbol", C);
return;
@@ -409,7 +418,7 @@
return;
}
- reportBug(*Str, C);
+ reportBug(*Str, C, ArgVal);
}
void ento::registerExprInspectionChecker(CheckerManager &Mgr) {
Index: clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
@@ -92,7 +92,17 @@
if (Field) {
State = State->BindExpr(CE, C.getLocationContext(),
nonloc::SymbolVal(Field));
- C.addTransition(State);
+ const NoteTag *InterestingTag =
+ C.getNoteTag([Cont, Field](BugReport &BR) -> std::string {
+ auto *PSBR = dyn_cast<PathSensitiveBugReport>(&BR);
+ if (PSBR) {
+ if (PSBR->isInteresting(Field)) {
+ PSBR->markInteresting(Cont);
+ }
+ }
+ return "";
+ });
+ C.addTransition(State, InterestingTag);
return;
}
}
Index: clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
@@ -715,6 +715,13 @@
}
return C.getNoteTag([Text, Name, ContReg](BugReport &BR) -> std::string {
+ const auto *PSBR = dyn_cast<PathSensitiveBugReport>(&BR);
+ if (!PSBR)
+ return "";
+
+ if (!PSBR->isInteresting(ContReg))
+ return "";
+
SmallString<256> Msg;
llvm::raw_svector_ostream Out(Msg);
Out << "Container " << (!Name.empty() ? ("'" + Name.str() + "' ") : "" )
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits