summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/AnalysisBasedWarnings.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-01-21 19:41:41 +0000
committerTed Kremenek <kremenek@apple.com>2011-01-21 19:41:41 +0000
commit39fa05634287190fa5898715dc66ac68ce5028ef (patch)
tree013592f1b6250b363089e10c095e9d9d222c61fc /clang/lib/Sema/AnalysisBasedWarnings.cpp
parenta834200dbe3ca1164198d8b79454c0f21c1c5a0d (diff)
downloadbcm5719-llvm-39fa05634287190fa5898715dc66ac68ce5028ef.tar.gz
bcm5719-llvm-39fa05634287190fa5898715dc66ac68ce5028ef.zip
Enhance -Wuninitialized-experimental diagnostics
to issue the warning at an uninitialized variable's declaration, but to issue notes at possible uninitialized uses (which could be multiple). llvm-svn: 123994
Diffstat (limited to 'clang/lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r--clang/lib/Sema/AnalysisBasedWarnings.cpp54
1 files changed, 51 insertions, 3 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index eb8590d60cb..67ddbf5bf98 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -364,14 +364,62 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
//===----------------------------------------------------------------------===//
namespace {
+struct SLocSort {
+ bool operator()(const DeclRefExpr *a, const DeclRefExpr *b) {
+ SourceLocation aLoc = a->getLocStart();
+ SourceLocation bLoc = b->getLocStart();
+ return aLoc.getRawEncoding() < bLoc.getRawEncoding();
+ }
+};
+
class UninitValsDiagReporter : public UninitVariablesHandler {
Sema &S;
+ typedef llvm::SmallVector<const DeclRefExpr *, 2> UsesVec;
+ typedef llvm::DenseMap<const VarDecl *, UsesVec*> UsesMap;
+ UsesMap *uses;
+
public:
- UninitValsDiagReporter(Sema &S) : S(S) {}
+ UninitValsDiagReporter(Sema &S) : S(S), uses(0) {}
+ ~UninitValsDiagReporter() {
+ flushDiagnostics();
+ }
void handleUseOfUninitVariable(const DeclRefExpr *dr, const VarDecl *vd) {
- S.Diag(dr->getLocStart(), diag::warn_var_is_uninit)
- << vd->getDeclName() << dr->getSourceRange();
+ if (!uses)
+ uses = new UsesMap();
+
+ UsesVec *&vec = (*uses)[vd];
+ if (!vec)
+ vec = new UsesVec();
+
+ vec->push_back(dr);
+ }
+
+ void flushDiagnostics() {
+ if (!uses)
+ return;
+
+ for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) {
+ const VarDecl *vd = i->first;
+ UsesVec *vec = i->second;
+
+ S.Diag(vd->getLocStart(), diag::warn_var_is_uninit)
+ << vd->getDeclName() << vd->getSourceRange();
+
+ // Sort the uses by their SourceLocations. While not strictly
+ // guaranteed to produce them in line/column order, this will provide
+ // a stable ordering.
+ std::sort(vec->begin(), vec->end(), SLocSort());
+
+ for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi)
+ {
+ const DeclRefExpr *dr = *vi;
+ S.Diag(dr->getLocStart(), diag::note_var_is_uninit)
+ << vd->getDeclName() << dr->getSourceRange();
+ }
+ delete vec;
+ }
+ delete uses;
}
};
}
OpenPOWER on IntegriCloud