summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/AnalysisBasedWarnings.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-09-12 18:49:10 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-09-12 18:49:10 +0000
commitba8071ec81eb5c39f8ebb869a18181a1ed25c782 (patch)
treec186ec14ec3cd2de5ac5930e7d63b6c3a7ccf8c0 /clang/lib/Sema/AnalysisBasedWarnings.cpp
parent16a4d8c15d873a5d19338a13004e6086bb7a3d45 (diff)
downloadbcm5719-llvm-ba8071ec81eb5c39f8ebb869a18181a1ed25c782.tar.gz
bcm5719-llvm-ba8071ec81eb5c39f8ebb869a18181a1ed25c782.zip
PR16054: Slight strengthening for -Wsometimes-uninitialized: if we use a
variable uninitialized every time we reach its (reachable) declaration, or every time we call the surrounding function, promote the warning from -Wmaybe-uninitialized to -Wsometimes-uninitialized. This is still slightly weaker than desired: we should, in general, warn if a use is uninitialized the first time it is evaluated. llvm-svn: 190623
Diffstat (limited to 'clang/lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r--clang/lib/Sema/AnalysisBasedWarnings.cpp52
1 files changed, 42 insertions, 10 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 599c4861267..7893a459c19 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -493,6 +493,31 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,
bool IsCapturedByBlock) {
bool Diagnosed = false;
+ switch (Use.getKind()) {
+ case UninitUse::Always:
+ S.Diag(Use.getUser()->getLocStart(), diag::warn_uninit_var)
+ << VD->getDeclName() << IsCapturedByBlock
+ << Use.getUser()->getSourceRange();
+ return;
+
+ case UninitUse::AfterDecl:
+ case UninitUse::AfterCall:
+ S.Diag(VD->getLocation(), diag::warn_sometimes_uninit_var)
+ << VD->getDeclName() << IsCapturedByBlock
+ << (Use.getKind() == UninitUse::AfterDecl ? 4 : 5)
+ << const_cast<DeclContext*>(VD->getLexicalDeclContext())
+ << VD->getSourceRange();
+ S.Diag(Use.getUser()->getLocStart(), diag::note_uninit_var_use)
+ << IsCapturedByBlock << Use.getUser()->getSourceRange();
+ return;
+
+ case UninitUse::Maybe:
+ case UninitUse::Sometimes:
+ // Carry on to report sometimes-uninitialized branches, if possible,
+ // or a 'may be used uninitialized' diagnostic otherwise.
+ break;
+ }
+
// Diagnose each branch which leads to a sometimes-uninitialized use.
for (UninitUse::branch_iterator I = Use.branch_begin(), E = Use.branch_end();
I != E; ++I) {
@@ -515,14 +540,10 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,
: (I->Output ? "1" : "0");
FixItHint Fixit1, Fixit2;
- switch (Term->getStmtClass()) {
+ switch (Term ? Term->getStmtClass() : Stmt::DeclStmtClass) {
default:
// Don't know how to report this. Just fall back to 'may be used
- // uninitialized'. This happens for range-based for, which the user
- // can't explicitly fix.
- // FIXME: This also happens if the first use of a variable is always
- // uninitialized, eg "for (int n; n < 10; ++n)". We should report that
- // with the 'is uninitialized' diagnostic.
+ // uninitialized'. FIXME: Can this happen?
continue;
// "condition is true / condition is false".
@@ -583,6 +604,17 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,
else
Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
break;
+ case Stmt::CXXForRangeStmtClass:
+ if (I->Output == 1) {
+ // The use occurs if a range-based for loop's body never executes.
+ // That may be impossible, and there's no syntactic fix for this,
+ // so treat it as a 'may be uninitialized' case.
+ continue;
+ }
+ DiagKind = 1;
+ Str = "for";
+ Range = cast<CXXForRangeStmt>(Term)->getRangeInit()->getSourceRange();
+ break;
// "condition is true / loop is exited".
case Stmt::DoStmtClass:
@@ -619,9 +651,7 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,
}
if (!Diagnosed)
- S.Diag(Use.getUser()->getLocStart(),
- Use.getKind() == UninitUse::Always ? diag::warn_uninit_var
- : diag::warn_maybe_uninit_var)
+ S.Diag(Use.getUser()->getLocStart(), diag::warn_maybe_uninit_var)
<< VD->getDeclName() << IsCapturedByBlock
<< Use.getUser()->getSourceRange();
}
@@ -1233,7 +1263,9 @@ public:
private:
static bool hasAlwaysUninitializedUse(const UsesVec* vec) {
for (UsesVec::const_iterator i = vec->begin(), e = vec->end(); i != e; ++i) {
- if (i->getKind() == UninitUse::Always) {
+ if (i->getKind() == UninitUse::Always ||
+ i->getKind() == UninitUse::AfterCall ||
+ i->getKind() == UninitUse::AfterDecl) {
return true;
}
}
OpenPOWER on IntegriCloud