[cfe-commits] r47774 - in /cfe/trunk: Analysis/GRExprEngine.cpp Analysis/GRSimpleVals.cpp include/clang/Analysis/PathSensitive/GRExprEngine.h

Ted Kremenek kremenek at apple.com
Fri Feb 29 15:14:48 PST 2008


Author: kremenek
Date: Fri Feb 29 17:14:48 2008
New Revision: 47774

URL: http://llvm.org/viewvc/llvm-project?rev=47774&view=rev
Log:
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.

Modified:
    cfe/trunk/Analysis/GRExprEngine.cpp
    cfe/trunk/Analysis/GRSimpleVals.cpp
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h

Modified: cfe/trunk/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRExprEngine.cpp?rev=47774&r1=47773&r2=47774&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/Analysis/GRExprEngine.cpp Fri Feb 29 17:14:48 2008
@@ -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;
       }

Modified: cfe/trunk/Analysis/GRSimpleVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRSimpleVals.cpp?rev=47774&r1=47773&r2=47774&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/Analysis/GRSimpleVals.cpp Fri Feb 29 17:14:48 2008
@@ -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();

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=47774&r1=47773&r2=47774&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Fri Feb 29 17:14:48 2008
@@ -90,6 +90,7 @@
   typedef llvm::SmallPtrSet<NodeTy*,2> UndefBranchesTy;  
   typedef llvm::SmallPtrSet<NodeTy*,2> UndefStoresTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> BadDerefTy;
+  typedef llvm::SmallPtrSet<NodeTy*,2> BadCallsTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> BadDividesTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> NoReturnCallsTy;  
   typedef llvm::SmallPtrSet<NodeTy*,2> UndefResultsTy;  
@@ -127,6 +128,10 @@
   ///  by the result is not.  Excludes divide-by-zero errors.
   UndefResultsTy UndefResults;
   
+  /// BadCalls - Nodes in the ExplodedGraph resulting from calls to function
+  ///  pointers that are NULL (or other constants) or Undefined.
+  BadCallsTy BadCalls;
+  
   bool StateCleaned;
   
 public:
@@ -194,6 +199,10 @@
     return N->isSink() && UndefResults.count(const_cast<NodeTy*>(N)) != 0;
   }
   
+  bool isBadCall(const NodeTy* N) const {
+    return N->isSink() && BadCalls.count(const_cast<NodeTy*>(N)) != 0;
+  }
+  
   typedef BadDerefTy::iterator null_deref_iterator;
   null_deref_iterator null_derefs_begin() { return ExplicitNullDeref.begin(); }
   null_deref_iterator null_derefs_end() { return ExplicitNullDeref.end(); }
@@ -209,6 +218,10 @@
   typedef UndefResultsTy::iterator undef_result_iterator;
   undef_result_iterator undef_results_begin() { return UndefResults.begin(); }
   undef_result_iterator undef_results_end() { return UndefResults.end(); }
+
+  typedef BadCallsTy::iterator bad_calls_iterator;
+  bad_calls_iterator bad_calls_begin() { return BadCalls.begin(); }
+  bad_calls_iterator bad_calls_end() { return BadCalls.end(); }  
   
   /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
   ///  nodes by processing the 'effects' of a block-level statement.  





More information about the cfe-commits mailing list