diff --git a/clang/Analysis/GRExprEngine.cpp b/clang/Analysis/GRExprEngine.cpp index 415c616bf902..660ed1badba7 100644 --- a/clang/Analysis/GRExprEngine.cpp +++ b/clang/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/clang/Analysis/GRSimpleVals.cpp b/clang/Analysis/GRSimpleVals.cpp index a2b6c95d2f50..a28ff1cf59bc 100644 --- a/clang/Analysis/GRSimpleVals.cpp +++ b/clang/Analysis/GRSimpleVals.cpp @@ -22,6 +22,38 @@ using namespace clang; namespace clang { +template +static inline const PostStmt& GetLocation(ITERATOR I) { + return cast((*I)->getLocation()); +} + +template <> +static inline const PostStmt& GetLocation(GRExprEngine::undef_arg_iterator I) { + return cast(I->first->getLocation()); +} + +template +static void EmitDiag(Diagnostic& Diag, SourceManager& SrcMgr, + unsigned ErrorDiag, ITERATOR I) { + + Expr* Exp = cast(GetLocation(I).getStmt()); + cast(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(GetLocation(I).getStmt()); + Expr* E2 = cast(I->second); + + SourceLocation Loc = E1->getExprLoc(); + SourceRange R = E2->getSourceRange(); + Diag.Report(FullSourceLoc(Loc, SrcMgr), ErrorDiag, 0, 0, &R, 1); +} + template 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 CachedErrors; - + llvm::SmallPtrSet 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((*I)->getLocation()); - Expr* Exp = cast(L.getStmt()); - - Diag.Report(FullSourceLoc(Exp->getExprLoc(), SrcMgr), ErrorDiag); + + EmitDiag(Diag, SrcMgr, ErrorDiag, I); } } diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h index 3ad87b2e7569..3a4e358d66b7 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -91,7 +91,7 @@ protected: typedef llvm::SmallPtrSet UndefStoresTy; typedef llvm::SmallPtrSet BadDerefTy; typedef llvm::SmallPtrSet BadCallsTy; - typedef llvm::SmallPtrSet UndefArgsTy; + typedef llvm::DenseMap UndefArgsTy; typedef llvm::SmallPtrSet BadDividesTy; typedef llvm::SmallPtrSet NoReturnCallsTy; typedef llvm::SmallPtrSet UndefResultsTy; @@ -209,7 +209,8 @@ public: } bool isUndefArg(const NodeTy* N) const { - return N->isSink() && UndefArgs.count(const_cast(N)) != 0; + return N->isSink() && + UndefArgs.find(const_cast(N)) != UndefArgs.end(); } typedef BadDerefTy::iterator null_deref_iterator;