]> granicus.if.org Git - clang/commitdiff
Add out-of-bound memory access warning report code.
authorZhongxing Xu <xuzhongxing@gmail.com>
Sun, 23 Nov 2008 05:52:28 +0000 (05:52 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Sun, 23 Nov 2008 05:52:28 +0000 (05:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59903 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/GRExprEngine.h
lib/Analysis/GRExprEngine.cpp
lib/Analysis/GRExprEngineInternalChecks.cpp

index 1b7d9bf6a396ba6c40686e202addfed7cc45b95d..765bc27df074bc711fe74d2eeb61c651d668d2c7 100644 (file)
@@ -105,6 +105,7 @@ public:
   typedef llvm::SmallPtrSet<NodeTy*,2> UndefResultsTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> RetsStackAddrTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> RetsUndefTy;
+  typedef llvm::SmallPtrSet<NodeTy*,2> OutOfBoundMemAccessesTy;
   
 protected:
 
@@ -170,6 +171,14 @@ protected:
   ///   message expressions where a pass-by-value argument has an undefined
   ///  value.
   UndefArgsTy MsgExprUndefArgs;
+
+  /// OutOfBoundMemAccesses - Nodes in the ExplodedGraph resulting from
+  /// out-of-bound memory accesses where the index MAY be out-of-bound.
+  OutOfBoundMemAccessesTy ImplicitOOBMemAccesses;
+
+  /// OutOfBoundMemAccesses - Nodes in the ExplodedGraph resulting from
+  /// out-of-bound memory accesses where the index MUST be out-of-bound.
+  OutOfBoundMemAccessesTy ExplicitOOBMemAccesses;
   
 public:
   GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, LiveVariables& L,
@@ -282,7 +291,7 @@ public:
   bool isUndefArg(const NodeTy* N) const {
     return N->isSink() &&
       (UndefArgs.find(const_cast<NodeTy*>(N)) != UndefArgs.end() ||
-       MsgExprUndefArgs.find(const_cast<NodeTy*>(N)) != MsgExprUndefArgs.end());            
+       MsgExprUndefArgs.find(const_cast<NodeTy*>(N)) != MsgExprUndefArgs.end());
   }
   
   bool isUndefReceiver(const NodeTy* N) const {
@@ -362,7 +371,21 @@ public:
   undef_receivers_iterator undef_receivers_end() {
     return UndefReceivers.end();
   }
-  
+
+  typedef OutOfBoundMemAccessesTy::iterator oob_memacc_iterator;
+  oob_memacc_iterator implicit_oob_memacc_begin() { 
+    return ImplicitOOBMemAccesses.begin();
+  }
+  oob_memacc_iterator implicit_oob_memacc_end() {
+    return ImplicitOOBMemAccesses.end();
+  }
+  oob_memacc_iterator explicit_oob_memacc_begin() {
+    return ExplicitOOBMemAccesses.begin();
+  }
+  oob_memacc_iterator explicit_oob_memacc_end() {
+    return ExplicitOOBMemAccesses.end();
+  }
+
   void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C);
   
   /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
index 6de910fc17187f611aaeef2e486fc53c8fa49f1b..084796cd994d432aa5baa6f235c7da9a14730c82 100644 (file)
@@ -1088,7 +1088,20 @@ const GRState* GRExprEngine::EvalLocation(Stmt* Ex, NodeTy* Pred,
       if (isFeasibleOutBound) {
         // Report warning.
 
-        StOutBound = 0;
+        // Make sink node manually.
+        ProgramPoint::Kind K = isLoad ? ProgramPoint::PostLoadKind
+                                      : ProgramPoint::PostStoreKind;
+
+        NodeTy* OOBNode = Builder->generateNode(Ex, StOutBound, Pred, K);
+
+        if (OOBNode) {
+          OOBNode->markAsSink();
+
+          if (isFeasibleInBound)
+            ImplicitOOBMemAccesses.insert(OOBNode);
+          else
+            ExplicitOOBMemAccesses.insert(OOBNode);
+        }
       }
 
       return isFeasibleInBound ? StInBound : NULL;
@@ -2529,8 +2542,8 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
         
         SVal LHSVal;
         
-        if (Result.isUnknown() && (Loc::IsLocType(CTy) ||
-                                 (CTy->isScalarType() && CTy->isIntegerType()))) {
+        if (Result.isUnknown() && (Loc::IsLocType(CTy) 
+                            || (CTy->isScalarType() && CTy->isIntegerType()))) {
           
           unsigned Count = Builder->getCurrentBlockCount();
           
@@ -2542,7 +2555,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
                  ? cast<SVal>(loc::SymbolVal(Sym)) 
                  : cast<SVal>(nonloc::SymbolVal(Sym));
           
-          // However, we need to convert the symbol to the computation type.          
+          // However, we need to convert the symbol to the computation type.
           Result = (LTy == CTy) ? LHSVal : EvalCast(LHSVal,CTy);
         }
         else {
index b4d4cb2c5686ce258b37fca3b358757ae59ee536..be7282314d077b1bb77d9e64098bc9bccbde5a94 100644 (file)
@@ -322,6 +322,16 @@ public:
   }
 };
 
+class VISIBILITY_HIDDEN OutOfBoundMemoryAccess : public BuiltinBug {
+public:
+  OutOfBoundMemoryAccess() : BuiltinBug("out-of-bound memory access",
+                       "Load or store into an out-of-bound memory position.") {}
+
+  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
+    Emit(BR, Eng.explicit_oob_memacc_begin(), Eng.explicit_oob_memacc_end());
+  }
+};
+
 //===----------------------------------------------------------------------===//
 // __attribute__(nonnull) checking
 
@@ -392,5 +402,6 @@ void GRExprEngine::RegisterInternalChecks() {
   Register(new BadArg());
   Register(new BadMsgExprArg());
   Register(new BadReceiver());
+  Register(new OutOfBoundMemoryAccess());
   AddCheck(new CheckAttrNonNull(), Stmt::CallExprClass); 
 }