]> granicus.if.org Git - clang/commitdiff
Enhanced pretty-printing of undefined-argument errors.
authorTed Kremenek <kremenek@apple.com>
Tue, 4 Mar 2008 00:42:54 +0000 (00:42 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 4 Mar 2008 00:42:54 +0000 (00:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47873 91177308-0d34-0410-b5e6-96231b3b80d8

Analysis/GRExprEngine.cpp
Analysis/GRSimpleVals.cpp
include/clang/Analysis/PathSensitive/GRExprEngine.h

index 415c616bf90287fd56951327d132660130d3c45f..660ed1badba72f700b0c1c2d4aae073497454299 100644 (file)
@@ -494,7 +494,7 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
 
         if (N) {
           N->markAsSink();
-          UndefArgs.insert(N);
+          UndefArgs[N] = CurrentArg;
         }
         
         continue;        
index a2b6c95d2f50b2db6dc387f94016532ffc61e520..a28ff1cf59bcca42977ef827dd5cfba4a1b34ad0 100644 (file)
@@ -22,6 +22,38 @@ using namespace clang;
 
 namespace clang {
 
+template <typename ITERATOR>
+static inline const PostStmt& GetLocation(ITERATOR I) {
+  return cast<PostStmt>((*I)->getLocation());
+}
+  
+template <>
+static inline const PostStmt& GetLocation(GRExprEngine::undef_arg_iterator I) {
+  return cast<PostStmt>(I->first->getLocation());
+}
+
+template <typename ITERATOR>
+static void EmitDiag(Diagnostic& Diag, SourceManager& SrcMgr,
+                     unsigned ErrorDiag, ITERATOR I) {  
+  
+  Expr* Exp = cast<Expr>(GetLocation(I).getStmt());
+  cast<Expr>(GetLocation(I).getStmt());  
+  Diag.Report(FullSourceLoc(Exp->getExprLoc(), SrcMgr), ErrorDiag);    
+}
+
+
+template <>
+static void EmitDiag(Diagnostic& Diag, SourceManager& SrcMgr,
+                     unsigned ErrorDiag, GRExprEngine::undef_arg_iterator I) {
+
+  Expr* E1 = cast<Expr>(GetLocation(I).getStmt());
+  Expr* E2 = cast<Expr>(I->second);
+  
+  SourceLocation Loc = E1->getExprLoc();
+  SourceRange R = E2->getSourceRange();
+  Diag.Report(FullSourceLoc(Loc, SrcMgr), ErrorDiag, 0, 0, &R, 1);
+}
+
 template <typename ITERATOR>
 static void EmitWarning(Diagnostic& Diag, SourceManager& SrcMgr,
                         ITERATOR I, ITERATOR E, const char* msg) {
@@ -32,8 +64,7 @@ static void EmitWarning(Diagnostic& Diag, SourceManager& SrcMgr,
   
   bool isFirst = true;
   unsigned ErrorDiag;
-  llvm::SmallPtrSet<void*,10> CachedErrors;
-  
+  llvm::SmallPtrSet<void*,10> CachedErrors;  
   
   for (; I != E; ++I) {
   
@@ -46,18 +77,15 @@ static void EmitWarning(Diagnostic& Diag, SourceManager& SrcMgr,
       // HACK: Cache the location of the error.  Don't emit the same
       // warning for the same error type that occurs at the same program
       // location but along a different path.
-      void* p = (*I)->getLocation().getRawData();
+      void* p = GetLocation(I).getRawData();
 
       if (CachedErrors.count(p))
         continue;
       
       CachedErrors.insert(p);
     }
-  
-    const PostStmt& L = cast<PostStmt>((*I)->getLocation());
-    Expr* Exp = cast<Expr>(L.getStmt());
-  
-    Diag.Report(FullSourceLoc(Exp->getExprLoc(), SrcMgr), ErrorDiag);
+    
+    EmitDiag(Diag, SrcMgr, ErrorDiag, I);  
   }
 }
   
index 3ad87b2e7569919762c65a0accd90b5b7598bbb2..3a4e358d66b7c9c28ecea3cf92626235db116bcd 100644 (file)
@@ -91,7 +91,7 @@ protected:
   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::DenseMap<NodeTy*, Expr*> UndefArgsTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> BadDividesTy;
   typedef llvm::SmallPtrSet<NodeTy*,2> NoReturnCallsTy;  
   typedef llvm::SmallPtrSet<NodeTy*,2> UndefResultsTy;  
@@ -209,7 +209,8 @@ public:
   }
   
   bool isUndefArg(const NodeTy* N) const {
-    return N->isSink() && UndefArgs.count(const_cast<NodeTy*>(N)) != 0;
+    return N->isSink() &&
+           UndefArgs.find(const_cast<NodeTy*>(N)) != UndefArgs.end();
   }
   
   typedef BadDerefTy::iterator null_deref_iterator;