xazax.hun added a comment.

In https://reviews.llvm.org/D40560#947514, @NoQ wrote:

> Replaced the live expression hack with a slightly better approach. It doesn't 
> update the live variables analysis to take `CFGNewAllocator` into account, 
> but at least tests now pass.
>
> In order to keep the return value produced by the `operator new()` call 
> around until `CXXNewExpr` is evaluated, i added a program state trait, 
> `CXXNewAllocatorValueStack`:
>
> 1. Upon evaluating `CFGNewAllocator`, the return `SVal` of the evaluated 
> allocator call is put here;
> 2. Upon evaluating `CXXConstructExpr`, that return value is retrieved from 
> here;
> 3. Upon evaluating `CXXNewExpr`, the return value is retrieved from here 
> again and then wiped.
>
>   In order to support nested allocator calls, this state trait is organized 
> as a stack/FIFO, with push in `CFGNewAllocator` and pop in `CXXNewExpr`. The 
> `llvm::ImmutableList` thing offers some asserts for warning us when we popped 
> more times than we pushed; we might want to add more asserts here to detect 
> other mismatches, but i don't see a need for implementing this as an 
> environment-like map from (`Expr`, `LocationContext`) to SVal.


I think it would be great to have tests for such cases to make it apparent it 
is not trivial to do this only based on the cfg.
Maybe something like:

  A *a = new A(new B, coin ? new C : new D, inlinedCallWithMoreAllocs()); 

Or in case it turns out to be an easy problem to match these from CFG, I prefer 
avoiding the state.

Also having a new expression within an overloaded operator new might be 
interesting.

> Why `SVal` and not `MemRegion`? Because i believe that ideally we want to 
> produce constructor calls with null or undefined `this`-arguments. 
> Constructors into null pointers should be skipped - this is how `operator 
> new(std::nothrow)` works, for instance. Constructors into garbage pointers 
> should be immediately caught by the checkers (to throw a warning and generate 
> a sink), but we still need to produce them so that the checkers could catch 
> them. But for now `CXXConstructorCall` has room only for one pointer, which 
> is currently `const MemRegion *`, so this still remains to be tackled.

Are you sure we need to produce undef vals? Couldn't a checker subscribe to the 
post allocator call and check for the undefined value and generate a sink 
before the constructor call? I am not opposed to using SVals there, just 
curious.

> Also we need to make sure that not only the expression lives, but also its 
> value lives, with all the various traits attached to it. Hence the new 
> facility in `ExprEngine::removeDead()` to mark the values in 
> `CXXNewAllocatorValueStack` as live. Test included in `new-ctor-inlined.cpp` 
> (the one with `s != 0`) covers this situation.
> 
> Some doxygen comments updated.




https://reviews.llvm.org/D40560



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

Reply via email to