The checker alpha.security.ArrayBoundV2 was implemented with a check::Location callback, so it triggered on memory read or write operations (and checked memory operations that handled ElementRegions).
The generality of this solution was elegant, but I'm replacing it with an implementation based on check::PreStmt<ArraySubscriptExpr>, because that'll be a better base for implementing intuitive and detailed error reports.
The logic for simplifying symbolically handled inequalities is unchanged and the existing unit tests pass under then new implementation without changes. Moreover, I'm highlighting the imprevements with four unit tests that all fail before this commit and pass with this commit:
(1) The case test_indirect_use() shows that the new code places the bug report at the location where an array is indexed incorrectly, while the old implementation placed the bug report in use_ptr() where the bad ElementRegion was accessed. I think this new behavior is more intuitive and basically a prerequisite for producing high quality error reports.
(2) The case test_multidim_generic() shows that the old logic badly mishandled multidimensional arrays.
(3) The case test_field() reveals that the old logic didn't notice memory access that touched only a FieldRegion inside an erroneous ElementRegion.
(4) The case test_in_unknown_space() shows that the checker had ignored all underflows occuring in UnknownSpaceRegion (i.e. memory accessed via unknown pointers) even if they happened in a well-structured area.
Among these issues (1) needed the switch to check::PreStmt, (2) and (3) are more elegant with check::PreStmt, but could've been solved with check::Location, and (4) is an independent improvement.
Finally, this commit also adds the testcases test_multidim_zero() and test_undersized_region() which are currently disabled, but should be fixed and enabled by followup commits.
This is the heuristic that I'm talking about in the main comment block. Note that the new code only strips ElementRegion layers where the type is the same, while the old code stripped all ElementRegion layers (and thus produced crazy FNs on multidimensional arrays).