diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-08-15 21:56:23 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-08-15 21:56:23 +0000 |
commit | 7f660857309a14c036a80ef90b40bf8f68fda9da (patch) | |
tree | ce02b420c45ce45f255370f25e56f4478e88d3fa /test/Analysis/method-call.cpp | |
parent | b5f9eb8a0709082bba8e8de3a6c643928570aaa0 (diff) |
[analyzer] If we call a C++ method on an object, assume it's non-null.
This is analogous to our handling of pointer dereferences: if we
dereference a pointer that may or may not be null, we assume it's non-null
from then on.
While some implementations of C++ (including ours) allow you to call a
non-virtual method through a null pointer of object type, it is technically
disallowed by the C++ standard, and should not prune out any real paths in
practice.
[class.mfct.non-static]p1: A non-static member function may be called
for an object of its class type, or for an object of a class derived
from its class type...
(a null pointer value does not refer to an object)
We can also make the same assumption about function pointers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161992 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Analysis/method-call.cpp')
-rw-r--r-- | test/Analysis/method-call.cpp | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/test/Analysis/method-call.cpp b/test/Analysis/method-call.cpp index 91da532456..912062739c 100644 --- a/test/Analysis/method-call.cpp +++ b/test/Analysis/method-call.cpp @@ -1,25 +1,37 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-store region -verify %s -// XFAIL: * void clang_analyzer_eval(bool); + struct A { int x; A(int a) { x = a; } int getx() const { return x; } }; +void testNullObject(A *a) { + clang_analyzer_eval(a); // expected-warning{{UNKNOWN}} + (void)a->getx(); // assume we know what we're doing + clang_analyzer_eval(a); // expected-warning{{TRUE}} +} + + +// FIXME: These require constructor inlining to be enabled. + void f1() { A x(3); - clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}} + // should be TRUE + clang_analyzer_eval(x.getx() == 3); // expected-warning{{UNKNOWN}} } void f2() { const A &x = A(3); - clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}} + // should be TRUE + clang_analyzer_eval(x.getx() == 3); // expected-warning{{UNKNOWN}} } void f3() { const A &x = (A)3; - clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}} + // should be TRUE + clang_analyzer_eval(x.getx() == 3); // expected-warning{{UNKNOWN}} } |