diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 30 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 11 |
2 files changed, 31 insertions, 10 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 3467dae4ba..ecfa821358 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -470,14 +470,25 @@ public: for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi) { const bool isAlwaysUninit = vi->second; + bool showDefinition = true; + if (const DeclRefExpr *dr = dyn_cast<DeclRefExpr>(vi->first)) { - S.Diag(dr->getLocStart(), - isAlwaysUninit ? - (isSelfInit(S.Context, vd, dr) - ? diag::warn_uninit_self_reference_in_init - : diag::warn_uninit_var) - : diag::warn_maybe_uninit_var) - << vd->getDeclName() << dr->getSourceRange(); + if (isAlwaysUninit) { + if (isSelfInit(S.Context, vd, dr)) { + S.Diag(dr->getLocStart(), + diag::warn_uninit_self_reference_in_init) + << vd->getDeclName() << vd->getLocation() << dr->getSourceRange(); + showDefinition = false; + } + else { + S.Diag(dr->getLocStart(), diag::warn_uninit_var) + << vd->getDeclName() << dr->getSourceRange(); + } + } + else { + S.Diag(dr->getLocStart(), diag::warn_maybe_uninit_var) + << vd->getDeclName() << dr->getSourceRange(); + } } else { const BlockExpr *be = cast<BlockExpr>(vi->first); @@ -488,8 +499,9 @@ public: } // Report where the variable was declared. - S.Diag(vd->getLocStart(), diag::note_uninit_var_def) - << vd->getDeclName(); + if (showDefinition) + S.Diag(vd->getLocStart(), diag::note_uninit_var_def) + << vd->getDeclName(); // Only report the fixit once. if (fixitIssued) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index e52082bbbf..8bf6c84c0b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4715,7 +4715,16 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, if (RealDecl == 0 || RealDecl->isInvalidDecl()) return; - SelfReferenceChecker(*this, RealDecl).VisitExpr(Init); + // Check for self-references within variable initializers. + if (VarDecl *vd = dyn_cast<VarDecl>(RealDecl)) { + // Variables declared within a function/method body are handled + // by a dataflow analysis. + if (!vd->hasLocalStorage() && !vd->isStaticLocal()) + SelfReferenceChecker(*this, RealDecl).VisitExpr(Init); + } + else { + SelfReferenceChecker(*this, RealDecl).VisitExpr(Init); + } if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) { // With declarators parsed the way they are, the parser cannot |