The SymbolReaper should consider a region live if that appears in
the store bindings anywhere - even if the region is wrapped by
RegionSymbolVals, SymbolicRegions or LazyCompoundVals.
This mistake by the SymbolReaper materialized in false-positives like
in the following example:
void ptr1(List* n) { List* n2 = new List(*n); // cctor if (!n->next) { if (n2->next) { clang_analyzer_warnIfReached(); // FP! This should be unreachable. } } delete n2; }
The store entry of the pointee of n2 looks something like this:
HeapSymRegion{conj_$1{List *, LC1, S2540, #1}} 0(Default) lazyCompoundVal{0x5641f1ed8830,Element{SymRegion{reg_$2<List * n>},0 S64b,struct List}}
So, any constraints referring to the VarRegion n supposed to be kept alive by that store binding.
Hence, the analyzer should be able to see that reg_$3<List * Element{SymRegion{reg_$2<List * n>},0 S64b,struct List}.next> { [0, 0] } when it reaches the n2->next.
This patch fixes the issue by reusing the SymbolReaper::markLive(MemRegion) for doing the appropriate traversal.
I'm yet to do the performance testing, given that this is actually in
the hot path.
Co-authored-by: Tomasz Kamiński <tomasz.kaminski@sonarsource.com>