[PATCH] D62926: [analyzer] ReturnVisitor: Bypass everything to see inlined calls
Artem Dergachev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 11 17:33:44 PDT 2019
NoQ added a comment.
All right, it seems that i'm completely misunderstanding this problem and we've been talking past each other this whole time.
The problem is not that we need to skip the `CXXConstructExpr`. The problem is that we need to skip `CXXNewExpr` (!!). CFG elements for an operator-new call go like this:
1. CFGAllocatorCall
2. CXXConstructExpr
3. CXXNewExpr
We're staring at element 3. The original loop says "hey, that's our statement! we've found it!". However, even though this is the statement that's taken as the call site, the respective ExplodedNode does not correspond to the end of the call. Instead, it corresponds to a moment of time after construction has finished and the new-expression is fully evaluated. So we need to ignore element 3. Then, element 2 is ignored automatically because the statements don't match. Then, we need to learn to recognize that element 1 is the right element, which is going to be either a `CallExitEnd` (if the allocator call was inlined) or dunno-but-definitely-not-`PostStmt` if the allocator was evaluated conservatively.
Bonus: the constructor is never inlined in our scenario, so it's easy to skip element 2, as it's going to be just PreStmt/PostStmt and no inlined call within it. Why? Because how the hell do you inline a constructor of a null pointer. The Standard guarantees that when the allocator returns a null pointer, the constructor is gracefully omitted. We currently have a FIXME in `prepareForObjectConstruction()` to implement this behavior:
179 // TODO: Detect when the allocator returns a null pointer.
180 // Constructor shall not be called in this case.
The current incorrect behavior is to instead evaluate the constructor conservatively, with a fake temporary region instead of the null pointer (this is generally the conservative approach to evaluating the constructor when object-under-construction is not known).
So my request to come up with a test case in which the constructor is going to be inlined was completely pointless. But in the general case we aren't really sure that it's going to be a null pointer (we may want to track an arbitrary value), so we shouldn't rely on that.
================
Comment at: clang/test/Analysis/new-ctor-null.cpp:37
S *s = new S();
// FIXME: Should be FALSE - we should not invalidate globals.
clang_analyzer_eval(global); // expected-warning{{UNKNOWN}}
----------------
This is essentially the same FIXME: the constructor should not have been evaluated, so in particular we should not invalidate globals.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D62926/new/
https://reviews.llvm.org/D62926
More information about the cfe-commits
mailing list