Add checks for function calls via a function pointer that is NULL, Undefined,
or otherwise a constant integer value that doesn't evaluate to an address.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47774 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp
index 2b94b4f..f05dd7a 100644
--- a/Analysis/GRExprEngine.cpp
+++ b/Analysis/GRExprEngine.cpp
@@ -507,11 +507,10 @@
 
     // Check for undefined control-flow.
 
-    if (L.isUndef()) {
-      
+    if (L.isUndef() || isa<lval::ConcreteInt>(L)) {      
       NodeTy* N = Builder->generateNode(CE, St, *DI);
       N->markAsSink();
-      UndefBranches.insert(N);
+      BadCalls.insert(N);
       continue;
     }
     
@@ -1591,7 +1590,8 @@
         GraphPrintCheckerState->isUndefStore(N) ||
         GraphPrintCheckerState->isUndefControlFlow(N) ||
         GraphPrintCheckerState->isBadDivide(N) ||
-        GraphPrintCheckerState->isUndefResult(N))
+        GraphPrintCheckerState->isUndefResult(N) ||
+        GraphPrintCheckerState->isBadCall(N))
       return "color=\"red\",style=\"filled\"";
     
     if (GraphPrintCheckerState->isNoReturnCall(N))
@@ -1623,26 +1623,22 @@
         
         L.getStmt()->printPretty(Out);
         
-        if (GraphPrintCheckerState->isImplicitNullDeref(N)) {
+        if (GraphPrintCheckerState->isImplicitNullDeref(N))
           Out << "\\|Implicit-Null Dereference.\\l";
-        }
-        else if (GraphPrintCheckerState->isExplicitNullDeref(N)) {
+        else if (GraphPrintCheckerState->isExplicitNullDeref(N))
           Out << "\\|Explicit-Null Dereference.\\l";
-        }
-        else if (GraphPrintCheckerState->isUndefDeref(N)) {
+        else if (GraphPrintCheckerState->isUndefDeref(N))
           Out << "\\|Dereference of undefialied value.\\l";
-        }
-        else if (GraphPrintCheckerState->isUndefStore(N)) {
+        else if (GraphPrintCheckerState->isUndefStore(N))
           Out << "\\|Store to Undefined LVal.";
-        }
-        else if (GraphPrintCheckerState->isBadDivide(N)) {
+        else if (GraphPrintCheckerState->isBadDivide(N))
           Out << "\\|Divide-by zero or undefined value.";
-        }
-        else if (GraphPrintCheckerState->isUndefResult(N)) {
+        else if (GraphPrintCheckerState->isUndefResult(N))
           Out << "\\|Result of operation is undefined.";
-        }
         else if (GraphPrintCheckerState->isNoReturnCall(N))
           Out << "\\|Call to function marked \"noreturn\".";
+        else if (GraphPrintCheckerState->isBadCall(N))
+          Out << "\\|Call to NULL/Undefined.";
         
         break;
       }
diff --git a/Analysis/GRSimpleVals.cpp b/Analysis/GRSimpleVals.cpp
index 366ffb7..d6c133f 100644
--- a/Analysis/GRSimpleVals.cpp
+++ b/Analysis/GRSimpleVals.cpp
@@ -101,6 +101,11 @@
               CheckerState->undef_results_begin(),
               CheckerState->undef_results_end(),
               "Result of operation is undefined.");
+  
+  EmitWarning(Diag, SrcMgr,
+              CheckerState->bad_calls_begin(),
+              CheckerState->bad_calls_end(),
+              "Call using a NULL or undefined function pointer value.");
       
 #ifndef NDEBUG
   if (Visualize) CheckerState->ViewGraph();