diff options
Diffstat (limited to 'lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 95 |
1 files changed, 52 insertions, 43 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index c818d40c77..6c95b60003 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -1,9 +1,8 @@ //=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis -*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -250,6 +249,10 @@ static void checkRecursiveFunction(Sema &S, const FunctionDecl *FD, CFG *cfg = AC.getCFG(); if (!cfg) return; + // If the exit block is unreachable, skip processing the function. + if (cfg->getExit().pred_empty()) + return; + // Emit diagnostic if a recursive function call is detected for all paths. if (checkForRecursiveFunctionCall(FD, cfg)) S.Diag(Body->getBeginLoc(), diag::warn_infinite_recursive_function); @@ -995,7 +998,8 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD, if (VD->getType()->isBlockPointerType() && !VD->hasAttr<BlocksAttr>()) S.Diag(BE->getBeginLoc(), diag::warn_uninit_byref_blockvar_captured_by_block) - << VD->getDeclName(); + << VD->getDeclName() + << VD->getType().getQualifiers().hasObjCLifetime(); else DiagUninitUse(S, VD, Use, true); } @@ -1639,15 +1643,11 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { return ONS; } - // Helper functions - void warnLockMismatch(unsigned DiagID, StringRef Kind, Name LockName, - SourceLocation Loc) { - // Gracefully handle rare cases when the analysis can't get a more - // precise source location. - if (!Loc.isValid()) - Loc = FunLocation; - PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName); - Warnings.emplace_back(std::move(Warning), getNotes()); + OptionalNotes makeLockedHereNote(SourceLocation LocLocked, StringRef Kind) { + return LocLocked.isValid() + ? getNotes(PartialDiagnosticAt( + LocLocked, S.PDiag(diag::note_locked_here) << Kind)) + : getNotes(); } public: @@ -1678,22 +1678,34 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { void handleUnmatchedUnlock(StringRef Kind, Name LockName, SourceLocation Loc) override { - warnLockMismatch(diag::warn_unlock_but_no_lock, Kind, LockName, Loc); - } - - void handleIncorrectUnlockKind(StringRef Kind, Name LockName, - LockKind Expected, LockKind Received, - SourceLocation Loc) override { if (Loc.isInvalid()) Loc = FunLocation; - PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_kind_mismatch) - << Kind << LockName << Received - << Expected); + PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_but_no_lock) + << Kind << LockName); Warnings.emplace_back(std::move(Warning), getNotes()); } - void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override { - warnLockMismatch(diag::warn_double_lock, Kind, LockName, Loc); + void handleIncorrectUnlockKind(StringRef Kind, Name LockName, + LockKind Expected, LockKind Received, + SourceLocation LocLocked, + SourceLocation LocUnlock) override { + if (LocUnlock.isInvalid()) + LocUnlock = FunLocation; + PartialDiagnosticAt Warning( + LocUnlock, S.PDiag(diag::warn_unlock_kind_mismatch) + << Kind << LockName << Received << Expected); + Warnings.emplace_back(std::move(Warning), + makeLockedHereNote(LocLocked, Kind)); + } + + void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation LocLocked, + SourceLocation LocDoubleLock) override { + if (LocDoubleLock.isInvalid()) + LocDoubleLock = FunLocation; + PartialDiagnosticAt Warning(LocDoubleLock, S.PDiag(diag::warn_double_lock) + << Kind << LockName); + Warnings.emplace_back(std::move(Warning), + makeLockedHereNote(LocLocked, Kind)); } void handleMutexHeldEndOfScope(StringRef Kind, Name LockName, @@ -1720,13 +1732,8 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << Kind << LockName); - if (LocLocked.isValid()) { - PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here) - << Kind); - Warnings.emplace_back(std::move(Warning), getNotes(Note)); - return; - } - Warnings.emplace_back(std::move(Warning), getNotes()); + Warnings.emplace_back(std::move(Warning), + makeLockedHereNote(LocLocked, Kind)); } void handleExclusiveAndShared(StringRef Kind, Name LockName, @@ -2082,16 +2089,16 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, // Register the expressions with the CFGBuilder. for (const auto &D : fscope->PossiblyUnreachableDiags) { - if (D.stmt) - AC.registerForcedBlockExpression(D.stmt); + for (const Stmt *S : D.Stmts) + AC.registerForcedBlockExpression(S); } if (AC.getCFG()) { analyzed = true; for (const auto &D : fscope->PossiblyUnreachableDiags) { - bool processed = false; - if (D.stmt) { - const CFGBlock *block = AC.getBlockForRegisteredExpression(D.stmt); + bool AllReachable = true; + for (const Stmt *S : D.Stmts) { + const CFGBlock *block = AC.getBlockForRegisteredExpression(S); CFGReverseBlockReachabilityAnalysis *cra = AC.getCFGReachablityAnalysis(); // FIXME: We should be able to assert that block is non-null, but @@ -2099,15 +2106,17 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, // edge cases; see test/Sema/vla-2.c. if (block && cra) { // Can this block be reached from the entrance? - if (cra->isReachable(&AC.getCFG()->getEntry(), block)) - S.Diag(D.Loc, D.PD); - processed = true; + if (!cra->isReachable(&AC.getCFG()->getEntry(), block)) { + AllReachable = false; + break; + } } + // If we cannot map to a basic block, assume the statement is + // reachable. } - if (!processed) { - // Emit the warning anyway if we cannot map to a basic block. + + if (AllReachable) S.Diag(D.Loc, D.PD); - } } } |