Enhanced pretty-printing of undefined-argument errors.

llvm-svn: 47873
This commit is contained in:
Ted Kremenek 2008-03-04 00:42:54 +00:00
parent 567d2e5b57
commit b2ce263891
3 changed files with 40 additions and 11 deletions

View File

@ -494,7 +494,7 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
if (N) {
N->markAsSink();
UndefArgs.insert(N);
UndefArgs[N] = CurrentArg;
}
continue;

View 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) {
@ -34,7 +66,6 @@ static void EmitWarning(Diagnostic& Diag, SourceManager& SrcMgr,
unsigned ErrorDiag;
llvm::SmallPtrSet<void*,10> CachedErrors;
for (; I != E; ++I) {
if (isFirst) {
@ -46,7 +77,7 @@ 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;
@ -54,10 +85,7 @@ static void EmitWarning(Diagnostic& Diag, SourceManager& SrcMgr,
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);
}
}

View 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;