aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Analysis/GRExprEngine.cpp2
-rw-r--r--Analysis/GRSimpleVals.cpp44
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h5
3 files changed, 40 insertions, 11 deletions
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp
index 415c616bf9..660ed1badb 100644
--- a/Analysis/GRExprEngine.cpp
+++ b/Analysis/GRExprEngine.cpp
@@ -494,7 +494,7 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
if (N) {
N->markAsSink();
- UndefArgs.insert(N);
+ UndefArgs[N] = CurrentArg;
}
continue;
diff --git a/Analysis/GRSimpleVals.cpp b/Analysis/GRSimpleVals.cpp
index a2b6c95d2f..a28ff1cf59 100644
--- a/Analysis/GRSimpleVals.cpp
+++ b/Analysis/GRSimpleVals.cpp
@@ -23,6 +23,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);
}
}
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index 3ad87b2e75..3a4e358d66 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -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;