llvm-project/clang/test/Analysis/runtime-regression.c
Donát Nagy 6e17ed9b04
[analyzer] Consolidate array bound checkers (#125534)
Before this commit, there were two alpha checkers that used different
algorithms/logic for detecting out of bounds memory access: the old
`alpha.security.ArrayBound` and the experimental, more complex
`alpha.security.ArrayBoundV2`.

After lots of quality improvement commits ArrayBoundV2 is now stable
enough to be moved out of the alpha stage. As indexing (and dereference)
are common operations, it still produces a significant amount of false
positives, but not much more than e.g. `core.NullDereference` or
`core.UndefinedBinaryOperatorResult`, so it should be acceptable as a
non-`core` checker.

At this point `alpha.security.ArrayBound` became obsolete (there is a
better tool for the same task), so I'm removing it from the codebase.
With this I can eliminate the ugly "V2" version mark almost everywhere
and rename `alpha.security.ArrayBoundV2` to `security.ArrayBound`.

(The version mark is preserved in the filename "ArrayBoundCheckerV2", to
ensure a clear git history. I'll rename it to "ArrayBoundChecker.cpp" in
a separate commit.)

This commit adapts the unit tests of `alpha.security.ArrayBound` to
testing the new `security.ArrayBound` (= old ArrayBoundV2). Currently
the names of the test files are very haphazard, I'll probably create a
separate followup commit that consolidates this.
2025-02-06 17:45:42 +01:00

56 lines
2.1 KiB
C

// RUN: %clang_analyze_cc1 %s \
// RUN: -analyzer-checker=core,security.ArrayBound \
// RUN: -analyzer-checker=debug.ExprInspection \
// RUN: -triple x86_64-unknown-linux-gnu \
// RUN: -verify
// This test is here to check if there is no significant run-time regression
// related to the assume machinery. The analysis should finish in less than 10
// seconds.
// expected-no-diagnostics
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint64_t;
int filter_slice_word(int sat_linesize, int sigma, int radius, uint64_t *sat,
uint64_t *square_sat, int width, int height,
int src_linesize, int dst_linesize, const uint16_t *src,
uint16_t *dst, int jobnr, int nb_jobs) {
const int starty = height * jobnr / nb_jobs;
const int endy = height * (jobnr + 1) / nb_jobs;
for (int y = starty; y < endy; y++) {
int lower_y = y - radius < 0 ? 0 : y - radius;
int higher_y = y + radius + 1 > height ? height : y + radius + 1;
int dist_y = higher_y - lower_y;
for (int x = 0; x < width; x++) {
int lower_x = x - radius < 0 ? 0 : x - radius;
int higher_x = x + radius + 1 > width ? width : x + radius + 1;
int count = dist_y * (higher_x - lower_x);
// The below hunk caused significant regression in run-time.
#if 1
uint64_t sum = sat[higher_y * sat_linesize + higher_x] -
sat[higher_y * sat_linesize + lower_x] -
sat[lower_y * sat_linesize + higher_x] +
sat[lower_y * sat_linesize + lower_x];
uint64_t square_sum = square_sat[higher_y * sat_linesize + higher_x] -
square_sat[higher_y * sat_linesize + lower_x] -
square_sat[lower_y * sat_linesize + higher_x] +
square_sat[lower_y * sat_linesize + lower_x];
uint64_t mean = sum / count;
uint64_t var = (square_sum - sum * sum / count) / count;
dst[y * dst_linesize + x] =
(sigma * mean + var * src[y * src_linesize + x]) / (sigma + var);
#endif
}
}
return 0;
}