[cfe-commits] r47778 - 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:53:11 PST 2008


Author: kremenek
Date: Fri Feb 29 17:53:11 2008
New Revision: 47778

URL: http://llvm.org/viewvc/llvm-project?rev=47778&view=rev
Log:
Added extra check for calls to functions where we pass undefined values
as arguments.

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=47778&r1=47777&r2=47778&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/Analysis/GRExprEngine.cpp Fri Feb 29 17:53:11 2008
@@ -481,12 +481,27 @@
     NodeSet DstTmp;  
     
     Visit(*AI, Pred, DstTmp);
+    
     if (DstTmp.empty()) DstTmp.Add(Pred);
     
+    Expr* CurrentArg = *AI;
     ++AI;
     
-    for (NodeSet::iterator DI=DstTmp.begin(), DE=DstTmp.end(); DI != DE; ++DI)
+    for (NodeSet::iterator DI=DstTmp.begin(), DE=DstTmp.end(); DI != DE; ++DI) {
+      if (GetRVal((*DI)->getState(), CurrentArg).isUndef()) {
+
+        NodeTy* N = Builder->generateNode(CE, (*DI)->getState(), *DI);
+
+        if (N) {
+          N->markAsSink();
+          UndefArgs.insert(N);
+        }
+        
+        continue;        
+      }
+
       VisitCall(CE, *DI, AI, AE, Dst);
+    }
     
     return;
   }
@@ -509,8 +524,10 @@
 
     if (L.isUndef() || isa<lval::ConcreteInt>(L)) {      
       NodeTy* N = Builder->generateNode(CE, St, *DI);
-      N->markAsSink();
-      BadCalls.insert(N);
+      if (N) {
+        N->markAsSink();
+        BadCalls.insert(N);
+      }
       continue;
     }
     
@@ -1591,7 +1608,8 @@
         GraphPrintCheckerState->isUndefControlFlow(N) ||
         GraphPrintCheckerState->isBadDivide(N) ||
         GraphPrintCheckerState->isUndefResult(N) ||
-        GraphPrintCheckerState->isBadCall(N))
+        GraphPrintCheckerState->isBadCall(N) ||
+        GraphPrintCheckerState->isUndefArg(N))
       return "color=\"red\",style=\"filled\"";
     
     if (GraphPrintCheckerState->isNoReturnCall(N))
@@ -1639,6 +1657,8 @@
           Out << "\\|Call to function marked \"noreturn\".";
         else if (GraphPrintCheckerState->isBadCall(N))
           Out << "\\|Call to NULL/Undefined.";
+        else if (GraphPrintCheckerState->isUndefArg(N))
+          Out << "\\|Argument in call is undefined";
         
         break;
       }

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

==============================================================================
--- cfe/trunk/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/Analysis/GRSimpleVals.cpp Fri Feb 29 17:53:11 2008
@@ -106,6 +106,11 @@
               CheckerState->bad_calls_begin(),
               CheckerState->bad_calls_end(),
               "Call using a NULL or undefined function pointer value.");
+  
+  EmitWarning(Diag, SrcMgr,
+              CheckerState->undef_arg_begin(),
+              CheckerState->undef_arg_end(),
+      "Pass-by-value argument in function or message expression is undefined.");
       
 #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=47778&r1=47777&r2=47778&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Fri Feb 29 17:53:11 2008
@@ -91,6 +91,7 @@
   typedef llvm::SmallPtrSet<NodeTy*,2> UndefStoresTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> BadDerefTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> BadCallsTy;
+  typedef llvm::SmallPtrSet<NodeTy*,2> UndefArgsTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> BadDividesTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> NoReturnCallsTy;  
   typedef llvm::SmallPtrSet<NodeTy*,2> UndefResultsTy;  
@@ -132,6 +133,10 @@
   ///  pointers that are NULL (or other constants) or Undefined.
   BadCallsTy BadCalls;
   
+  /// UndefArg - Nodes in the ExplodedGraph resulting from calls to functions
+  ///   where a pass-by-value argument has an undefined value.
+  UndefArgsTy UndefArgs;
+  
   bool StateCleaned;
   
 public:
@@ -203,6 +208,10 @@
     return N->isSink() && BadCalls.count(const_cast<NodeTy*>(N)) != 0;
   }
   
+  bool isUndefArg(const NodeTy* N) const {
+    return N->isSink() && UndefArgs.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(); }
@@ -223,6 +232,10 @@
   bad_calls_iterator bad_calls_begin() { return BadCalls.begin(); }
   bad_calls_iterator bad_calls_end() { return BadCalls.end(); }  
   
+  typedef UndefArgsTy::iterator undef_arg_iterator;
+  undef_arg_iterator undef_arg_begin() { return UndefArgs.begin(); }
+  undef_arg_iterator undef_arg_end() { return UndefArgs.end(); }  
+  
   /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
   ///  nodes by processing the 'effects' of a block-level statement.  
   void ProcessStmt(Stmt* S, StmtNodeBuilder& builder);    





More information about the cfe-commits mailing list