]> granicus.if.org Git - clang/commitdiff
[analyzer] Use a more robust check for null in CallAndMessageChecker.
authorJordan Rose <jordan_rose@apple.com>
Sat, 4 Aug 2012 01:04:52 +0000 (01:04 +0000)
committerJordan Rose <jordan_rose@apple.com>
Sat, 4 Aug 2012 01:04:52 +0000 (01:04 +0000)
This should fix the failing test on the buildbot as well.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161290 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
test/Analysis/misc-ps-region-store.cpp

index e09d6885a98a7bab259cc8c4b3c9f7388e17d8dc..30f45c7685b977cd17a116257956634517071c6a 100644 (file)
@@ -232,7 +232,11 @@ void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
     return;
   }
 
-  if (L.isZeroConstant()) {
+  ProgramStateRef StNonNull, StNull;
+  llvm::tie(StNonNull, StNull) = State->assume(cast<DefinedOrUnknownSVal>(L));
+
+  // FIXME: Do we want to record the non-null assumption here?
+  if (StNull && !StNonNull) {
     if (!BT_call_null)
       BT_call_null.reset(
         new BuiltinBug("Called function pointer is null (null dereference)"));
@@ -253,7 +257,13 @@ void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
       emitBadCall(BT_cxx_call_undef.get(), C, CC->getCXXThisExpr());
       return;
     }
-    if (V.isZeroConstant()) {
+
+    ProgramStateRef State = C.getState();
+    ProgramStateRef StNonNull, StNull;
+    llvm::tie(StNonNull, StNull) = State->assume(cast<DefinedOrUnknownSVal>(V));
+
+    // FIXME: Do we want to record the non-null assumption here?
+    if (StNull && !StNonNull) {
       if (!BT_cxx_call_null)
         BT_cxx_call_null.reset(new BuiltinBug("Called C++ object pointer "
                                               "is null"));
index fcffe075360fabcf4da22c9c3e02eac45df66091..e30cedb91189378731753f333543797e0321b38e 100644 (file)
@@ -272,11 +272,11 @@ const Rdar9212495_A& rdar9212495(const Rdar9212495_C* ptr) {
   const Rdar9212495_A& val = dynamic_cast<const Rdar9212495_A&>(*ptr);
   
   // This is not valid C++; dynamic_cast with a reference type will throw an
-  // exception if the pointer does not match the expected type.
+  // exception if the pointer does not match the expected type. However, our
+  // implementation of dynamic_cast will pass through a null pointer...or a
+  // "null reference"! So this branch is actually possible.
   if (&val == 0) {
-    val.bar(); // no warning (unreachable)
-    int *p = 0;
-    *p = 0xDEAD; // no warning (unreachable)
+    val.bar(); // expected-warning{{Called C++ object pointer is null}}
   }
   
   return val;