[PATCH] Teach the analyzer about multi-dimensional VLAs
Daniel Fahlgren
daniel at fahlgren.se
Mon Oct 20 14:58:11 PDT 2014
Hi Jordan,
On tor, 2014-10-16 at 09:21 -0700, Jordan Rose wrote:
> On Oct 14, 2014, at 15:12 , Daniel Fahlgren <daniel at fahlgren.se> wrote:
>
> > Hi Jordan,
> >
> > On ons, 2014-10-08 at 20:05 -0700, Jordan Rose wrote:
> >
> >> + // First only check for errors. That way we will find problems even
> >> if one of
> >> + // the dimensions is unknown.
> >> + const Expr *SE;
> >> + QualType QT;
> >> + do {
> >> + // Check size expression.
> >> + SE = VLA->getSizeExpr();
> >> + State = checkSizeExpr(SE, State, C);
> >> + if (!State)
> >> + return;
> >
> >> Seems like a worthy goal. If we're finding problems even if one
> >> dimension is unknown, though, is it worth finding problems in every
> >> size expression, rather than exiting early when we find a problem in
> >> the first one?
> >
> > Good point. I'm not sure I solved this the correct way. It seems like
> > it only is possible to create one sink node so I had to call
> > getPredecessor(). Is that the right way or how should I do to emit
> > multiple errors?
>
> It's more just the normal uniquing of identical nodes kicking in—if
> we've somehow already gotten to this state, that's supposed to mean
> we've already emitted any errors. I think that means you should collect
> all the errors up front and then emit them all on the same sink node.
> Emitting them on the predecessor would be valid but not really what we
> want, because it could have the wrong location.
Ah, thanks for the explanation. I've updated the patch to store all
errors in a vector, allowing to emit all of them on the same node.
> >> +
> >> + // Check next dimension.
> >> + QT = VLA->getElementType();
> >> + VLA = Ctx.getAsVariableArrayType(QT);
> >> + } while(VLA);
> >
> >> Nitpick: can you put a space after the "while"? (here and below)
> >
> > Ok.
> >
> >> + // Record the state so far, in case one of the lengths is unknown.
> >> + C.addTransition(State);
> >
> >> Unfortunately we can't actually do this—you end up recording
> >> two transitions here, rather than replacing the first one. Maybe the
> >> size calculation should be factored out into a helper function as
> >> well?
> >
> >> + // Multiply the current size by the element size.
> >> + ArraySizeVal = SvalBuilder.evalBinOpNN(State, BO_Mul,
> >> ArrayLength,
> >> + ArraySizeVal.castAs<NonLoc>(), SizeTy);
> >
> >> Can you add a FIXME in here to check for overflow? That's a security
> >> risk, really.
> >
> > I've broken out the calculation and added the FIXME, but that got me
> > thinking. What is a too large size? If the size is larger than a size_t
> > can represent we surely got a problem. We will most likely run out of
> > stack space way before that, however.
>
> On platforms where RSIZE_MAX exists and is smaller than SIZE_MAX the
> "most correct" answer is probably RSIZE_MAX. If not that, then we could
> perhaps make a policy of using SSIZE_MAX (or SIZE_MAX >> 1, which is
> how RSIZE_MAX is defined on my system anyway). But even just the simple
> case of overflowing a size_t would probably be good enough.
>
> Again, though, let's worry about this later. :-)
>
>
> >> As for the tests, can you add some assertions that we really do
> >> multiply the size out correctly? For example, using a too-large index
> >> should warn, casting to char * and assigning outside the buffer should
> >> warn, and sizeof should give the right answer.
> >
> > That turned out to be easier said than done. The analyzer doesn't seem
> > to handle sizeof on things that can't be resolved compile time (like
> > VLAs)? I've also added some FIXMEs for ArrayBoundV2. Casting to char *
> > works as expected.
>
> Huh, I thought we handled sizeof for a VLA by using the extent, but I
> guess not. Out-of-bounds checks it is.
>
> Jordan
Best regards,
Daniel Fahlgren
-------------- next part --------------
A non-text attachment was scrubbed...
Name: vla.patch
Type: text/x-patch
Size: 13486 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20141020/6648be22/attachment.bin>
More information about the cfe-commits
mailing list