[PATCH] D76996: [analyzer] Improve PlacementNewChecker
Artem Dergachev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 20 03:11:20 PDT 2020
NoQ added inline comments.
================
Comment at: clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp:125
+ Msg = std::string(llvm::formatv(
+ "Possibly not enough {0} bytes for array allocation which "
+ "requires "
----------------
f00kat wrote:
> martong wrote:
> > Maybe the below could be a wording that's more easy to follow?
> > `{0} bytes is possibly not enough for array allocation which ...`
> Yeah. Sure. I have some troubles with english :)
Why do we say "possibly"? Where does the uncertainty come from?
================
Comment at: clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp:189
+ if (const MemRegion *MRegion = PlaceVal.getAsRegion()) {
+ if (const ElementRegion *TheElementRegion =
+ MRegion->getAs<ElementRegion>()) {
----------------
martong wrote:
> f00kat wrote:
> > f00kat wrote:
> > > NoQ wrote:
> > > > NoQ wrote:
> > > > > The sequence of `FieldRegion`s and `ElementRegion`s on top of a base region may be arbitrary: `var.a[0].b[1][2].c.d[3]` etc.
> > > > >
> > > > > I'd rather unwrap those regions one-by-one in a loop and look at the alignment of each layer.
> > > > Alternatively, just decompose the whole region into base region and offset and see if base region has the necessary alignment and the offset is divisible by the necessary alignment.
> > > > The sequence of FieldRegions and ElementRegions on top of a base region may be arbitrary: var.a[0].b[1][2].c.d[3] etc.
> > >
> > > But i think(hope) I already do this and even have tests for this cases. For example
> > > ```void test22() {
> > > struct alignas(alignof(short)) Z {
> > > char p;
> > > char c[10];
> > > };
> > >
> > > struct Y {
> > > char p;
> > > Z b[10];
> > > };
> > >
> > > struct X {
> > > Y a[10];
> > > } Xi; // expected-note {{'Xi' initialized here}}
> > >
> > > // ok. 2(X align) + 1 (offset Y.p) + 1(align Z.p to 'short') + 1(offset Z.p) + 3(index)
> > > ::new (&Xi.a[0].b[0].c[3]) long;
> > > }```
> > >
> > > Cases with multidimensional arrays will also be handled correctly because method 'TheElementRegion->getAsArrayOffset()' calculates the offset for multidimensional arrays
> > > ```void testXX() {
> > > struct Y {
> > > char p;
> > > char b[10][10];
> > > };
> > >
> > > struct X {
> > > Y a[10];
> > > } Xi;
> > >
> > > ::new (&Xi.a[0].b[0][0]) long;
> > > }```
> > >
> > > I can explain the code below for ElementRegion if needed.
> > ?
> Yeah, the tests are convincing and I think that you are handling the regions well.
>
> On the other hand, this code is getting really complex, we should make it easier to read and understand.
> E.g. `FieldOffsetValue` should be explained more, is it the offset started from the the start address of the multidimensional array, or it is just the offset from one element's start address?
> Also, you have two variables named as `Offset`. They are offsets from which starting address? Perhaps we should have in the comments a running example, maybe for `&Xi.a[0].b[0][0]`? I mean is `FieldOffseValue` is standing for `b` or for `a`?
> Alternatively, just decompose the whole region into base region and offset and see if base region has the necessary alignment and the offset is divisible by the necessary alignment.
I expect this to be, like, 5 lines of code. I don't understand why the current code is so complicated, it looks like you're considering multiple cases but ultimately doing the same thing.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D76996/new/
https://reviews.llvm.org/D76996
More information about the cfe-commits
mailing list