diff options
author | DonĂ¡t Nagy <donat.nagy@ericsson.com> | 2024-07-22 11:44:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-22 11:44:20 +0200 |
commit | 2bc38dc30bc9baad610925d7e90e724a9d09ee7d (patch) | |
tree | 95d7b9a55acfbd10830c2dd6523b36cb7aa40eec /clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp | |
parent | 2e789900433834b3b5cd6a55ccf64da6a9ec4505 (diff) | |
download | llvm-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.cpp | 18 |
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. |