[PATCH] D69726: [analyzer] DynamicSize: Store the dynamic size

Csaba Dabis via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sat Mar 28 20:56:21 PDT 2020


Charusso added inline comments.


================
Comment at: clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h:25
 
-/// Get the stored dynamic size for the region \p MR.
+/// \returns The stored dynamic size for the region \p MR.
 DefinedOrUnknownSVal getDynamicSize(ProgramStateRef State, const MemRegion *MR,
----------------
NoQ wrote:
> Naming: I believe we should keep using the word "Extent". There's no need to introduce a new term for the existing concept; it makes it harder to explain on the mailing list :) Let's make a follow-up patch to change the naming back (so that not to screw the review).
Since then I have changed my mind when I have read about Environment and Store in a book. Sure, next up.


================
Comment at: clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h:41-44
+/// Set the dynamic size of a CXXNewExpr \p NE by its region \p MR.
+ProgramStateRef setDynamicSize(ProgramStateRef State, const MemRegion *MR,
+                               const CXXNewExpr *NE,
+                               const LocationContext *LCtx, SValBuilder &SVB);
----------------
NoQ wrote:
> This function is probably going to be used exactly once in the whole code. There's no need to turn it into a public API.
It is being used 3 times already, so I believe it is a cool API.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp:99
+          .Case("clang_analyzer_region", &ExprInspectionChecker::analyzerRegion)
+          .Case("clang_analyzer_size", &ExprInspectionChecker::analyzerDumpSize)
+          .Case("clang_analyzer_elementCount",
----------------
NoQ wrote:
> `clang_analyzer_dump_extent()`? Or just `clang_analyzer_dump(clang_analyzer_getExtent())`.
I like the shorter version, but of course I have seen the longer version.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp:283
+  llvm::raw_svector_ostream Out(Msg);
+  Out << MR;
+  reportBug(Out.str(), C);
----------------
NoQ wrote:
> So, how is it different from the existing `clang_analyzer_dump()`?
I wanted to make it for the derived regions, but then I have realized I am lazy to dig into the buggier parts of the Analyzer. Removed.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp:310-311
+
+  QualType Ty = TVR ? TVR->getDesugaredValueType(C.getASTContext())
+                    : CE->getArg(0)->IgnoreParenImpCasts()->getType();
+
----------------
NoQ wrote:
> How is this better than `getValueType()`? Are you sure you're not getting a pointer type instead in the `!TVR` case? I.e., can you test this on a non-heap `SymRegion`?
> How is this better than getValueType()?
Consistency. We get the static ~~size~~ extent by getting the desugared type which most likely just an extra overhead.

> Are you sure you're not getting a pointer type instead in the !TVR case? I.e., can you test this on a non-heap SymRegion?
The issue was the `var_region_simple_ptr` test: we need to use regex for checking after the `}}` token where `/ 4` is the correct result. I did not really get why the test pass.


================
Comment at: clang/lib/StaticAnalyzer/Core/DynamicSize.cpp:85
+    if (CI->getValue().isUnsigned())
+      Size = SVB.makeIntVal(CI->getValue(), /*IsUnsigned=*/false);
+
----------------
NoQ wrote:
> Charusso wrote:
> > That one is interesting. Some of the checkers / SValBuilder(?) generate unsigned integers which should not happen, I believe. May we need a FIXME and an assertion about signedness. What do you think?
> `SymbolExtent` has type `size_t` and both `malloc` and `operator new` accept `size_t` as a parameter. Therefore everything needs to be //unsigned// and we need to assert this.
> 
> That said, array indexes are //signed// (as per implementation of `ElementRegion`).
It was a premature optimization for consistency. I will leave the signedness as is, FIXME added.


================
Comment at: clang/test/Analysis/misc-ps-region-store.m:1190
+        tmp2[x] = am; // expected-warning \
+        {{Access out-of-bound array element (buffer overflow)}}
       }
----------------
NoQ wrote:
> Charusso wrote:
> > That is the single regression which I do not get.
> Well, please debug. Like, look at the full report, dump egraph, see what changed. Try to `creduce` the example further under the condition "behavior changed with the patch", maybe that'll clear something up (though if it's a true positive after creduce it doesn't guarantee that it's a true positive before creduce).
Given that I have no access for `rdar` I did my hand-reduce and the solution is the following:
```lang=c
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 \
// RUN:  -analyzer-checker=core,alpha.security.ArrayBound \
// RUN:  -verify %s

static void RDar8424269_B(int unknown) {
  unsigned char tmp2t[1][unknown];
  tmp2t[1][13] = 0; // expected-warning \
    {{Access out-of-bound array element (buffer overflow)}}
}
```

Looking at the master branch `core.VLASize` created the constraint `extent_$1{tmp2} {[0, 0]}` without any state splits. The new behavior does not create random constraints so that an alpha checker could detect we have no information about the unknown ~~size~~ extent.

Given that the alpha checker cannot catch the following: `char foo[bar]; foo[13] = 0;` is assumed that the problem is the VLASizeChecker's modeling which has a FIXME: `Handle multi-dimensional VLAs.` but does not handle this case.

An easy and appropriate fix to detect the multi-dimensional array. Here is the way to obtain the inner dimensions: http://clang-developers.42468.n3.nabble.com/Multi-dimensional-arrays-td4028727.html

So that the final solution is:
```lang=diff
   // FIXME: Handle multi-dimensional VLAs.
+  if (VLA->getElementType()->getAsArrayTypeUnsafe())
+    return;
```

I hope with that I have fixed even more Bugzilla issues. May it would be interesting to see why the ~~size~~ extent of the array got a constraint of being `0`, but I leave it as an exercise for the reader.


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

https://reviews.llvm.org/D69726





More information about the cfe-commits mailing list