[cfe-commits] r59764 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRExprEngine.h lib/Analysis/GRExprEngine.cpp lib/Analysis/GRExprEngineInternalChecks.cpp

Ted Kremenek kremenek at apple.com
Thu Nov 20 16:27:56 PST 2008


Author: kremenek
Date: Thu Nov 20 18:27:44 2008
New Revision: 59764

URL: http://llvm.org/viewvc/llvm-project?rev=59764&view=rev
Log:
- Clean up transfer function logic for 'return' statements.
- Add check for returning an undefined value to a caller.

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

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=59764&r1=59763&r2=59764&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Thu Nov 20 18:27:44 2008
@@ -104,12 +104,17 @@
   typedef llvm::SmallPtrSet<NodeTy*,2> NoReturnCallsTy;  
   typedef llvm::SmallPtrSet<NodeTy*,2> UndefResultsTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> RetsStackAddrTy;
+  typedef llvm::SmallPtrSet<NodeTy*,2> RetsUndefTy;
   
 protected:
 
   /// RetsStackAddr - Nodes in the ExplodedGraph that result from returning
   ///  the address of a stack variable.
   RetsStackAddrTy RetsStackAddr;
+
+  /// RetsUndef - Nodes in the ExplodedGraph that result from returning
+  ///  an undefined value.
+  RetsUndefTy RetsUndef;
   
   /// UndefBranches - Nodes in the ExplodedGraph that result from
   ///  taking a branch based on an undefined value.
@@ -288,6 +293,10 @@
   ret_stackaddr_iterator ret_stackaddr_begin() { return RetsStackAddr.begin(); }
   ret_stackaddr_iterator ret_stackaddr_end() { return RetsStackAddr.end(); }  
   
+  typedef RetsUndefTy::iterator ret_undef_iterator;
+  ret_undef_iterator ret_undef_begin() { return RetsUndef.begin(); }
+  ret_undef_iterator ret_undef_end() { return RetsUndef.end(); }
+  
   typedef UndefBranchesTy::iterator undef_branch_iterator;
   undef_branch_iterator undef_branches_begin() { return UndefBranches.begin(); }
   undef_branch_iterator undef_branches_end() { return UndefBranches.end(); }  

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Thu Nov 20 18:27:44 2008
@@ -2246,47 +2246,37 @@
     return;
   }
 
-  NodeSet DstRet;
-  QualType T = R->getType();
-  
-  if (T->isPointerLikeType()) {
-    
-    // Check if any of the return values return the address of a stack variable.
-    
-    NodeSet Tmp;
-    Visit(R, Pred, Tmp);
-    
-    for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-      SVal X = GetSVal((*I)->getState(), R);
-
-      if (isa<loc::MemRegionVal>(X)) {
-        
-        // Determine if the value is on the stack.
-        const MemRegion* R = cast<loc::MemRegionVal>(&X)->getRegion();
+  NodeSet Tmp;
+  Visit(R, Pred, Tmp);
 
-        if (R && getStateManager().hasStackStorage(R)) {
-        
-          // Create a special node representing the v
-          
-          NodeTy* RetStackNode = Builder->generateNode(S, GetState(*I), *I);
-          
-          if (RetStackNode) {
-            RetStackNode->markAsSink();
-            RetsStackAddr.insert(RetStackNode);
-          }
-          
-          continue;
+  for (NodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
+    SVal X = GetSVal((*I)->getState(), R);
+    
+    // Check if we return the address of a stack variable.
+    if (isa<loc::MemRegionVal>(X)) {
+      // Determine if the value is on the stack.
+      const MemRegion* R = cast<loc::MemRegionVal>(&X)->getRegion();
+      
+      if (R && getStateManager().hasStackStorage(R)) {
+        // Create a special node representing the error.
+        if (NodeTy* N = Builder->generateNode(S, GetState(*I), *I)) {
+          N->markAsSink();
+          RetsStackAddr.insert(N);
         }
+        continue;
       }
-      
-      DstRet.Add(*I);
     }
-  }
-  else
-    Visit(R, Pred, DstRet);
-  
-  for (NodeSet::iterator I=DstRet.begin(), E=DstRet.end(); I!=E; ++I)
+    // Check if we return an undefined value.
+    else if (X.isUndef()) {
+      if (NodeTy* N = Builder->generateNode(S, GetState(*I), *I)) {
+        N->markAsSink();
+        RetsUndef.insert(N);
+      }
+      continue;
+    }
+    
     EvalReturn(Dst, S, *I);
+  }
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp?rev=59764&r1=59763&r2=59764&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp Thu Nov 20 18:27:44 2008
@@ -180,7 +180,7 @@
     }    
   }
 };
-  
+
 class VISIBILITY_HIDDEN RetStack : public BuiltinBug {
 public:
   RetStack() : BuiltinBug("return of stack address") {}
@@ -239,7 +239,16 @@
     }
   }
 };
-
+  
+class VISIBILITY_HIDDEN RetUndef : public BuiltinBug {
+public:
+  RetUndef() : BuiltinBug("uninitialized return value",
+              "Uninitialized or undefined return value returned to caller.") {}
+  
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    Emit(BR, Eng.ret_undef_begin(), Eng.ret_undef_end());
+  }
+};
 
 class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
   struct VISIBILITY_HIDDEN FindUndefExpr {
@@ -379,6 +388,7 @@
   Register(new UndefResult());
   Register(new BadCall());
   Register(new RetStack());
+  Register(new RetUndef());
   Register(new BadArg());
   Register(new BadMsgExprArg());
   Register(new BadReceiver());





More information about the cfe-commits mailing list