aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
diff options
context:
space:
mode:
authorDonĂ¡t Nagy <donat.nagy@ericsson.com>2024-07-22 11:44:20 +0200
committerGitHub <noreply@github.com>2024-07-22 11:44:20 +0200
commit2bc38dc30bc9baad610925d7e90e724a9d09ee7d (patch)
tree95d7b9a55acfbd10830c2dd6523b36cb7aa40eec /clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
parent2e789900433834b3b5cd6a55ccf64da6a9ec4505 (diff)
downloadllvm-2bc38dc30bc9baad610925d7e90e724a9d09ee7d.zip
llvm-2bc38dc30bc9baad610925d7e90e724a9d09ee7d.tar.gz
llvm-2bc38dc30bc9baad610925d7e90e724a9d09ee7d.tar.bz2
[analyzer] Improve bug report hashing, merge similar reports (#98621)
Previously there were certain situations where alpha.security.ArrayBoundV2 produced lots of very similar and redundant reports that only differed in their full `Description` that contained the (negative) byte offset value. (See https://github.com/llvm/llvm-project/issues/86969 for details.) This change updates the `Profile()` method of `PathSensitiveBugReport` to ensure that it uses `getShortDescription()` instead of the full `Description` so the standard report deduplication eliminates most of these redundant reports. Note that the effects of this change are very limited because there are very few checkers that specify a separate short description, and so `getShortDescription()` practically always defaults to returning the full `Description`. For the sake of consistency `BasicBugReport::Profile()` is also updated to use the short description. (Right now there are no checkers that use `BasicBugReport` with separate long and short descriptions.) This commit also includes some small code quality improvements in `ArrayBoundV2` that are IMO too trivial to be moved into a separate commit.
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp18
1 files changed, 9 insertions, 9 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
index f82288f..3f83756 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
@@ -373,14 +373,14 @@ static std::optional<int64_t> getConcreteValue(std::optional<NonLoc> SV) {
}
static Messages getPrecedesMsgs(const SubRegion *Region, NonLoc Offset) {
- std::string RegName = getRegionName(Region);
- SmallString<128> Buf;
- llvm::raw_svector_ostream Out(Buf);
- Out << "Access of " << RegName << " at negative byte offset";
- if (auto ConcreteIdx = Offset.getAs<nonloc::ConcreteInt>())
- Out << ' ' << ConcreteIdx->getValue();
- return {formatv("Out of bound access to memory preceding {0}", RegName),
- std::string(Buf)};
+ std::string RegName = getRegionName(Region), OffsetStr = "";
+
+ if (auto ConcreteOffset = getConcreteValue(Offset))
+ OffsetStr = formatv(" {0}", ConcreteOffset);
+
+ return {
+ formatv("Out of bound access to memory preceding {0}", RegName),
+ formatv("Access of {0} at negative byte offset{1}", RegName, OffsetStr)};
}
/// Try to divide `Val1` and `Val2` (in place) by `Divisor` and return true if
@@ -609,7 +609,7 @@ void ArrayBoundCheckerV2::performCheck(const Expr *E, CheckerContext &C) const {
// CHECK UPPER BOUND
DefinedOrUnknownSVal Size = getDynamicExtent(State, Reg, SVB);
if (auto KnownSize = Size.getAs<NonLoc>()) {
- // In a situation where both overflow and overflow are possible (but the
+ // In a situation where both underflow and overflow are possible (but the
// index is either tainted or known to be invalid), the logic of this
// checker will first assume that the offset is non-negative, and then
// (with this additional assumption) it will detect an overflow error.