baloghadamsoftware created this revision.
baloghadamsoftware added reviewers: NoQ, Szelethus.
baloghadamsoftware added a project: clang.
Herald added subscribers: martong, steakhal, Charusso, gamesh411, donat.nagy,
mikhail.ramalho, a.sidorin, rnkovacs, szepet, xazax.hun, whisperity.
baloghadamsoftware added a parent revision: D73720: [Analyzer] Use note tags to
track container begin and and changes.
If an error happens which is related to a container the Container Modeling
checker adds note tags to all the container operations along the bug path. This
may be disturbing if there are other containers beside the one which is
affected by the bug. This patch restricts the note tags to only the affected
container and adjust the debug checkers to be able to test this change.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D75514
Files:
clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.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/DebugContainerModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
@@ -52,6 +52,9 @@
bool evalCall(const CallEvent &Call, CheckerContext &C) const;
};
+bool contains(const SourceManager &SM, const SourceRange Outer,
+ SourceRange Inner);
+
} //namespace
DebugContainerModeling::DebugContainerModeling() {
@@ -92,7 +95,17 @@
if (Field) {
State = State->BindExpr(CE, C.getLocationContext(),
nonloc::SymbolVal(Field));
- C.addTransition(State);
+ const auto &SM = C.getSourceManager();
+ const NoteTag *InterestingTag =
+ C.getNoteTag([Cont, CE, &SM](BugReport &BR) -> std::string {
+ auto *PSBR = dyn_cast<PathSensitiveBugReport>(&BR);
+ if (PSBR && contains(SM, PSBR->getRanges()[0],
+ CE->getSourceRange())) {
+ PSBR->markInteresting(Cont);
+ }
+ return "";
+ });
+ C.addTransition(State, InterestingTag);
return;
}
}
@@ -129,6 +142,18 @@
return N;
}
+namespace {
+
+bool contains(const SourceManager &SM, const SourceRange Outer,
+ SourceRange Inner) {
+ SourceLocation OB = Outer.getBegin(), OE = Outer.getEnd(),
+ IB = Inner.getBegin(), IE = Inner.getEnd();
+ return (OB == IB || SM.isBeforeInTranslationUnit(OB, IB)) &&
+ (IE == OE || SM.isBeforeInTranslationUnit(IE, OE));
+}
+
+} // namespace
+
void ento::registerDebugContainerModeling(CheckerManager &mgr) {
mgr.registerChecker<DebugContainerModeling>();
}
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() + "' ") : "" )
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/DebugContainerModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
@@ -52,6 +52,9 @@
bool evalCall(const CallEvent &Call, CheckerContext &C) const;
};
+bool contains(const SourceManager &SM, const SourceRange Outer,
+ SourceRange Inner);
+
} //namespace
DebugContainerModeling::DebugContainerModeling() {
@@ -92,7 +95,17 @@
if (Field) {
State = State->BindExpr(CE, C.getLocationContext(),
nonloc::SymbolVal(Field));
- C.addTransition(State);
+ const auto &SM = C.getSourceManager();
+ const NoteTag *InterestingTag =
+ C.getNoteTag([Cont, CE, &SM](BugReport &BR) -> std::string {
+ auto *PSBR = dyn_cast<PathSensitiveBugReport>(&BR);
+ if (PSBR && contains(SM, PSBR->getRanges()[0],
+ CE->getSourceRange())) {
+ PSBR->markInteresting(Cont);
+ }
+ return "";
+ });
+ C.addTransition(State, InterestingTag);
return;
}
}
@@ -129,6 +142,18 @@
return N;
}
+namespace {
+
+bool contains(const SourceManager &SM, const SourceRange Outer,
+ SourceRange Inner) {
+ SourceLocation OB = Outer.getBegin(), OE = Outer.getEnd(),
+ IB = Inner.getBegin(), IE = Inner.getEnd();
+ return (OB == IB || SM.isBeforeInTranslationUnit(OB, IB)) &&
+ (IE == OE || SM.isBeforeInTranslationUnit(IE, OE));
+}
+
+} // namespace
+
void ento::registerDebugContainerModeling(CheckerManager &mgr) {
mgr.registerChecker<DebugContainerModeling>();
}
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