diff options
| author | Artem Dergachev <artem.dergachev@gmail.com> | 2018-01-17 22:51:19 +0000 |
|---|---|---|
| committer | Artem Dergachev <artem.dergachev@gmail.com> | 2018-01-17 22:51:19 +0000 |
| commit | beba5307463158c5b5cfbe7c1be987e781a81e69 (patch) | |
| tree | fa180b8632a366dca31672360645f92971088848 /clang/test | |
| parent | 6b3e48b46a6e2b3283a9d37cfa3e0ac9c2ff91bb (diff) | |
| download | bcm5719-llvm-beba5307463158c5b5cfbe7c1be987e781a81e69.tar.gz bcm5719-llvm-beba5307463158c5b5cfbe7c1be987e781a81e69.zip | |
[analyzer] operator new: Model the cast of returned pointer into object type.
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
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/Analysis/new-ctor-conservative.cpp | 15 | ||||
| -rw-r--r-- | clang/test/Analysis/new-ctor-inlined.cpp | 15 |
2 files changed, 30 insertions, 0 deletions
diff --git a/clang/test/Analysis/new-ctor-conservative.cpp b/clang/test/Analysis/new-ctor-conservative.cpp index ce0ad464656..4500e3a253d 100644 --- a/clang/test/Analysis/new-ctor-conservative.cpp +++ b/clang/test/Analysis/new-ctor-conservative.cpp @@ -12,3 +12,18 @@ void checkConstructorInlining() { S *s = new S; clang_analyzer_eval(s->x == 1); // expected-warning{{TRUE}} } + +void checkNewPOD() { + int *i = new int; + clang_analyzer_eval(*i == 0); // expected-warning{{UNKNOWN}} + int *j = new int(); + clang_analyzer_eval(*j == 0); // expected-warning{{TRUE}} + int *k = new int(5); + clang_analyzer_eval(*k == 5); // expected-warning{{TRUE}} +} + +void checkNewArray() { + S *s = new S[10]; + // FIXME: Should be true once we inline array constructors. + clang_analyzer_eval(s[0].x == 1); // expected-warning{{UNKNOWN}} +} diff --git a/clang/test/Analysis/new-ctor-inlined.cpp b/clang/test/Analysis/new-ctor-inlined.cpp index d16b9b1d287..1506bf27f35 100644 --- a/clang/test/Analysis/new-ctor-inlined.cpp +++ b/clang/test/Analysis/new-ctor-inlined.cpp @@ -38,3 +38,18 @@ void checkNestedNew() { Sp *p = new Sp(new Sp(0)); clang_analyzer_eval(p->p->p == 0); // expected-warning{{TRUE}} } + +void checkNewPOD() { + int *i = new int; + clang_analyzer_eval(*i == 0); // expected-warning{{UNKNOWN}} + int *j = new int(); + clang_analyzer_eval(*j == 0); // expected-warning{{TRUE}} + int *k = new int(5); + clang_analyzer_eval(*k == 5); // expected-warning{{TRUE}} +} + +void checkTrivialCopy() { + S s; + S *t = new S(s); // no-crash + clang_analyzer_eval(t->x == 1); // expected-warning{{TRUE}} +} |

