[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
diff --git a/test/Analysis/func.c b/test/Analysis/func.c
index b6cebde..709ebf7 100644
--- a/test/Analysis/func.c
+++ b/test/Analysis/func.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -verify %s
+
+void clang_analyzer_eval(int);
void f(void) {
void (*p)(void);
@@ -13,3 +15,13 @@
void f2() {
g(f);
}
+
+void f3(void (*f)(void), void (*g)(void)) {
+ clang_analyzer_eval(!f); // expected-warning{{UNKNOWN}}
+ f();
+ clang_analyzer_eval(!f); // expected-warning{{FALSE}}
+
+ clang_analyzer_eval(!g); // expected-warning{{UNKNOWN}}
+ (*g)();
+ clang_analyzer_eval(!g); // expected-warning{{FALSE}}
+}