According to [basic.stc.dynamic.allocation], the return type of any C++
overloaded operator new() is "void *". However, type of the new-expression
"new T()" and the type of "this" during construction of "T" are both "T *".
Hence an implicit cast, which is not present in the AST, needs to be performed
before the construction. This patch adds such cast in the case when the
allocator was indeed inlined. For now, in the case where the allocator was *not*
inlined we still use the same symbolic value (which is a pure SymbolicRegion of
type "T *") because it is consistent with how we represent the casts and causes
less surprise in the checkers after switching to the new behavior.
The better approach would be to represent that value as a cast over a
SymbolicRegion of type "void *", however we have technical difficulties
conjuring such region without any actual expression of type "void *" present in
the AST.
Differential Revision: https://reviews.llvm.org/D41250
rdar://problem/12180598
llvm-svn: 322777
The -analyzer-config c++-allocator-inlining experimental option allows the
analyzer to reason about C++ operator new() similarly to how it reasons about
regular functions. In this mode, operator new() is correctly called before the
construction of an object, with the help of a special CFG element.
However, the subsequent construction of the object was still not performed into
the region of memory returned by operator new(). The patch fixes it.
Passing the value from operator new() to the constructor and then to the
new-expression itself was tricky because operator new() has no call site of its
own in the AST. The new expression itself is not a good call site because it
has an incorrect type (operator new() returns 'void *', while the new expression
is a pointer to the allocated object type). Additionally, lifetime of the new
expression in the environment makes it unsuitable for passing the value.
For that reason, an additional program state trait is introduced to keep track
of the return value.
Finally this patch relaxes restrictions on the memory region class that are
required for inlining the constructor. This change affects the old mode as well
(c++-allocator-inlining=false) and seems safe because these restrictions were
an overkill compared to the actual problems observed.
Differential Revision: https://reviews.llvm.org/D40560
rdar://problem/12180598
llvm-svn: 322774