diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /clang/lib/Sema/AnalysisBasedWarnings.cpp | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'clang/lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 04611dadde66..3b7356893833 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -974,6 +974,14 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use, << Use.getUser()->getSourceRange(); } +/// Diagnose uninitialized const reference usages. +static bool DiagnoseUninitializedConstRefUse(Sema &S, const VarDecl *VD, + const UninitUse &Use) { + S.Diag(Use.getUser()->getBeginLoc(), diag::warn_uninit_const_reference) + << VD->getDeclName() << Use.getUser()->getSourceRange(); + return true; +} + /// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an /// uninitialized variable. This manages the different forms of diagnostic /// emitted for particular types of uses. Returns true if the use was diagnosed @@ -1506,13 +1514,14 @@ class UninitValsDiagReporter : public UninitVariablesHandler { // order of diagnostics when calling flushDiagnostics(). typedef llvm::MapVector<const VarDecl *, MappedType> UsesMap; UsesMap uses; + UsesMap constRefUses; public: UninitValsDiagReporter(Sema &S) : S(S) {} ~UninitValsDiagReporter() override { flushDiagnostics(); } - MappedType &getUses(const VarDecl *vd) { - MappedType &V = uses[vd]; + MappedType &getUses(UsesMap &um, const VarDecl *vd) { + MappedType &V = um[vd]; if (!V.getPointer()) V.setPointer(new UsesVec()); return V; @@ -1520,11 +1529,17 @@ public: void handleUseOfUninitVariable(const VarDecl *vd, const UninitUse &use) override { - getUses(vd).getPointer()->push_back(use); + getUses(uses, vd).getPointer()->push_back(use); + } + + void handleConstRefUseOfUninitVariable(const VarDecl *vd, + const UninitUse &use) override { + getUses(constRefUses, vd).getPointer()->push_back(use); } void handleSelfInit(const VarDecl *vd) override { - getUses(vd).setInt(true); + getUses(uses, vd).setInt(true); + getUses(constRefUses, vd).setInt(true); } void flushDiagnostics() { @@ -1571,6 +1586,32 @@ public: } uses.clear(); + + // Flush all const reference uses diags. + for (const auto &P : constRefUses) { + const VarDecl *vd = P.first; + const MappedType &V = P.second; + + UsesVec *vec = V.getPointer(); + bool hasSelfInit = V.getInt(); + + if (!vec->empty() && hasSelfInit && hasAlwaysUninitializedUse(vec)) + DiagnoseUninitializedUse(S, vd, + UninitUse(vd->getInit()->IgnoreParenCasts(), + /* isAlwaysUninit */ true), + /* alwaysReportSelfInit */ true); + else { + for (const auto &U : *vec) { + if (DiagnoseUninitializedConstRefUse(S, vd, U)) + break; + } + } + + // Release the uses vector. + delete vec; + } + + constRefUses.clear(); } private: @@ -1659,6 +1700,14 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { : getNotes(); } + OptionalNotes makeUnlockedHereNote(SourceLocation LocUnlocked, + StringRef Kind) { + return LocUnlocked.isValid() + ? getNotes(PartialDiagnosticAt( + LocUnlocked, S.PDiag(diag::note_unlocked_here) << Kind)) + : getNotes(); + } + public: ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL) : S(S), FunLocation(FL), FunEndLocation(FEL), @@ -1685,13 +1734,14 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { Warnings.emplace_back(std::move(Warning), getNotes()); } - void handleUnmatchedUnlock(StringRef Kind, Name LockName, - SourceLocation Loc) override { + void handleUnmatchedUnlock(StringRef Kind, Name LockName, SourceLocation Loc, + SourceLocation LocPreviousUnlock) override { if (Loc.isInvalid()) Loc = FunLocation; PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_but_no_lock) << Kind << LockName); - Warnings.emplace_back(std::move(Warning), getNotes()); + Warnings.emplace_back(std::move(Warning), + makeUnlockedHereNote(LocPreviousUnlock, Kind)); } void handleIncorrectUnlockKind(StringRef Kind, Name LockName, @@ -2184,7 +2234,8 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, if (!Diags.isIgnored(diag::warn_uninit_var, D->getBeginLoc()) || !Diags.isIgnored(diag::warn_sometimes_uninit_var, D->getBeginLoc()) || - !Diags.isIgnored(diag::warn_maybe_uninit_var, D->getBeginLoc())) { + !Diags.isIgnored(diag::warn_maybe_uninit_var, D->getBeginLoc()) || + !Diags.isIgnored(diag::warn_uninit_const_reference, D->getBeginLoc())) { if (CFG *cfg = AC.getCFG()) { UninitValsDiagReporter reporter(S); UninitVariablesAnalysisStats stats; |