donat.nagy accepted this revision.
donat.nagy added a comment.
This revision is now accepted and ready to land.

Thanks for the updates! I didn't spot any important issue, so I'm accepting 
this commit, but let's wait for the opinion of @steakhal before merging this.

In D158707#4613955 <https://reviews.llvm.org/D158707#4613955>, @danix800 wrote:

> In D158707#4613743 <https://reviews.llvm.org/D158707#4613743>, @donat.nagy 
> wrote:
>
>> [...] Does this commit fix the "root" of the issue by eliminating some 
>> misuse of correctly implemented (but perhaps surprising) `SVal` / `APSInt` 
>> arithmetic; or is there an underlying bug in the `SVal` / `APSInt` 
>> arithmetic which is just avoided (and not eliminated) by this commit? In the 
>> latter case, what obstacles prevent us from fixing the root cause?
>
> For the observed signed compared to unsigned unexpectation from ArrayBoundV2,
> the constraint manager does give the CORRECT result.
>
> It's a misuse of the constraint API, mainly caused by unexpected unsigned 
> extent
> set by memory modeling. Actually `ArrayBoundV2::getSimplifiedOffsets()` has 
> clear
> comment that this `signed <-> unsigned` comparison is problematic.
>
>   // TODO: once the constraint manager is smart enough to handle non 
> simplified
>   // symbolic expressions remove this function. Note that this can not be 
> used in
>   // the constraint manager as is, since this does not handle overflows. It is
>   // safe to assume, however, that memory offsets will not overflow.
>   // NOTE: callers of this function need to be aware of the effects of 
> overflows
>   // and signed<->unsigned conversions!
>   static std::pair<NonLoc, nonloc::ConcreteInt>
>   getSimplifiedOffsets(NonLoc offset, nonloc::ConcreteInt extent,
>                        SValBuilder &svalBuilder) {

In fact, the "NOTE:" comment was added by my patch D135375 
<https://reviews.llvm.org/D135375> (which eliminated lots of false positives 
caused by a situation when the argument `offset` was unsigned), but I was still 
confused by this new bug. (Where the other argument `extent` was unsigned and 
this led to incorrect conclusions like "`len` cannot be larger than `3u`, so 
`len` cannot be `-1`, because `-1` is larger than `3u`" 🙃 .) Thanks for 
troubleshooting this issue!



================
Comment at: clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp:34
+    if (auto SSize =
+            SVB.convertToArrayIndex(*Size).getAs<DefinedOrUnknownSVal>())
+      return *SSize;
----------------
I think it's a good convention if `getDynamicExtent()` will always return 
concrete values as `ArrayIndexTy`. (If I didn't miss some very obscure case, 
then this will be true when this commit is merged.) 


================
Comment at: clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp:49
+    return UnknownVal();
+  MR = MR->StripCasts();
+
----------------
Note that `StripCasts()` is overzealous and strips array indexing when the 
index is zero. For example if you have a rectangular matrix `int m[6][8];` then 
this function would (correctly) say that the element count of `m[1]` is 8, but 
it would claim that the element count of `m[0]` is 6 (because it strips the 
'cast' and calculates the element count of `m`).

This is caused by the hacky "solution" that casts are represented by 
`ElementRegion{original region, 0, new type}` which cannot be distinguished 
from a real element access where the index happens to be 0. (This is just a 
public service announcement, this already affects e.g. `getDynamicExtent` and I 
don't think that you can find a local solution. For more information, see also 
https://github.com/llvm/llvm-project/issues/42709 which plans to refactor the 
memory model.)


================
Comment at: clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp:72-75
+  auto ElementCount =
+      SVB.evalBinOp(State, BO_Div, Size, ElementSize, SVB.getArrayIndexType())
+          .getAs<DefinedOrUnknownSVal>();
+  return ElementCount ? *ElementCount : UnknownVal();
----------------
Perhaps use the method `value_or` of std::optional?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158707/new/

https://reviews.llvm.org/D158707

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to