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) { if (N) {
N->markAsSink(); N->markAsSink();
UndefArgs.insert(N); UndefArgs[N] = CurrentArg;
} }
continue; continue;

View File

@ -22,6 +22,38 @@ using namespace clang;
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> template <typename ITERATOR>
static void EmitWarning(Diagnostic& Diag, SourceManager& SrcMgr, static void EmitWarning(Diagnostic& Diag, SourceManager& SrcMgr,
ITERATOR I, ITERATOR E, const char* msg) { ITERATOR I, ITERATOR E, const char* msg) {
@ -32,8 +64,7 @@ static void EmitWarning(Diagnostic& Diag, SourceManager& SrcMgr,
bool isFirst = true; bool isFirst = true;
unsigned ErrorDiag; unsigned ErrorDiag;
llvm::SmallPtrSet<void*,10> CachedErrors; llvm::SmallPtrSet<void*,10> CachedErrors;
for (; I != E; ++I) { 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 // HACK: Cache the location of the error. Don't emit the same
// warning for the same error type that occurs at the same program // warning for the same error type that occurs at the same program
// location but along a different path. // location but along a different path.
void* p = (*I)->getLocation().getRawData(); void* p = GetLocation(I).getRawData();
if (CachedErrors.count(p)) if (CachedErrors.count(p))
continue; continue;
CachedErrors.insert(p); CachedErrors.insert(p);
} }
const PostStmt& L = cast<PostStmt>((*I)->getLocation()); EmitDiag(Diag, SrcMgr, ErrorDiag, I);
Expr* Exp = cast<Expr>(L.getStmt());
Diag.Report(FullSourceLoc(Exp->getExprLoc(), SrcMgr), ErrorDiag);
} }
} }

View File

@ -91,7 +91,7 @@ protected:
typedef llvm::SmallPtrSet<NodeTy*,2> UndefStoresTy; typedef llvm::SmallPtrSet<NodeTy*,2> UndefStoresTy;
typedef llvm::SmallPtrSet<NodeTy*,2> BadDerefTy; typedef llvm::SmallPtrSet<NodeTy*,2> BadDerefTy;
typedef llvm::SmallPtrSet<NodeTy*,2> BadCallsTy; 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> BadDividesTy;
typedef llvm::SmallPtrSet<NodeTy*,2> NoReturnCallsTy; typedef llvm::SmallPtrSet<NodeTy*,2> NoReturnCallsTy;
typedef llvm::SmallPtrSet<NodeTy*,2> UndefResultsTy; typedef llvm::SmallPtrSet<NodeTy*,2> UndefResultsTy;
@ -209,7 +209,8 @@ public:
} }
bool isUndefArg(const NodeTy* N) const { 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; typedef BadDerefTy::iterator null_deref_iterator;