AnalysisBasedWarnings.cpp revision 651f13cea278ec967336033dd032faef0e9fc2ec
12e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis -*- C++ -*-=//
22e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//
32e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//                     The LLVM Compiler Infrastructure
42e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//
52e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// This file is distributed under the University of Illinois Open Source
62e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// License. See LICENSE.TXT for details.
72e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//
82e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//===----------------------------------------------------------------------===//
92e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//
102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// This file defines analysis_warnings::[Policy,Executor].
112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// Together they are used by Sema to issue warnings based on inexpensive
122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// static analysis algorithms in libAnalysis.
132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//
142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//===----------------------------------------------------------------------===//
152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/Sema/AnalysisBasedWarnings.h"
172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/AST/DeclCXX.h"
182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/AST/DeclObjC.h"
192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/AST/EvaluatedExprVisitor.h"
202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/AST/ExprCXX.h"
212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/AST/ExprObjC.h"
222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/AST/ParentMap.h"
232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/AST/RecursiveASTVisitor.h"
242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/AST/StmtCXX.h"
252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/AST/StmtObjC.h"
262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/AST/StmtVisitor.h"
272e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
282e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/Analysis/Analyses/Consumed.h"
292e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/Analysis/Analyses/ReachableCode.h"
302e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/Analysis/Analyses/ThreadSafety.h"
31c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "clang/Analysis/Analyses/UninitializedValues.h"
32c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "clang/Analysis/AnalysisContext.h"
332e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/Analysis/CFG.h"
342e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/Analysis/CFGStmtMap.h"
352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/Basic/SourceLocation.h"
36b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org#include "clang/Basic/SourceManager.h"
37b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org#include "clang/Lex/Lexer.h"
382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/Lex/Preprocessor.h"
392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/Sema/ScopeInfo.h"
402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "clang/Sema/SemaInternal.h"
412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "llvm/ADT/ArrayRef.h"
422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "llvm/ADT/BitVector.h"
432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "llvm/ADT/FoldingSet.h"
442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "llvm/ADT/ImmutableMap.h"
452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "llvm/ADT/MapVector.h"
462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "llvm/ADT/PostOrderIterator.h"
472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "llvm/ADT/SmallString.h"
482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "llvm/ADT/SmallVector.h"
492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "llvm/ADT/StringRef.h"
502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include "llvm/Support/Casting.h"
512e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include <algorithm>
522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include <deque>
532e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include <iterator>
542e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org#include <vector>
552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
562e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgusing namespace clang;
572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
582e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//===----------------------------------------------------------------------===//
592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// Unreachable code analysis.
602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//===----------------------------------------------------------------------===//
612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
622e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgnamespace {
632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  class UnreachableCodeHandler : public reachable_code::Callback {
642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    Sema &S;
652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  public:
662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    UnreachableCodeHandler(Sema &s) : S(s) {}
672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    void HandleUnreachable(reachable_code::UnreachableKind UK,
692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                           SourceLocation L,
702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                           SourceRange SilenceableCondVal,
712e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                           SourceRange R1,
722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                           SourceRange R2) override {
732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      unsigned diag = diag::warn_unreachable;
742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      switch (UK) {
752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        case reachable_code::UK_Break:
762e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          diag = diag::warn_unreachable_break;
772e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          break;
782e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        case reachable_code::UK_Return:
792e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          diag = diag::warn_unreachable_return;
802e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          break;
812e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        case reachable_code::UK_Loop_Increment:
822e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          diag = diag::warn_unreachable_loop_increment;
832e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          break;
842e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        case reachable_code::UK_Other:
852e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          break;
862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      }
872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      S.Diag(L, diag) << R1 << R2;
892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      SourceLocation Open = SilenceableCondVal.getBegin();
912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      if (Open.isValid()) {
922e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        SourceLocation Close = SilenceableCondVal.getEnd();
932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        Close = S.PP.getLocForEndOfToken(Close);
942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        if (Close.isValid()) {
952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          S.Diag(Open, diag::note_unreachable_silence)
962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            << FixItHint::CreateInsertion(Open, "/* DISABLES CODE */ (")
972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            << FixItHint::CreateInsertion(Close, ")");
982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        }
992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      }
1002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
1012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  };
1022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
1032e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// CheckUnreachable - Check for unreachable code.
105c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgstatic void CheckUnreachable(Sema &S, AnalysisDeclContext &AC) {
106c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // As a heuristic prune all diagnostics not in the main file.  Currently
107c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // the majority of warnings in headers are false positives.  These
1082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // are largely caused by configuration state, e.g. preprocessor
1092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // defined code, etc.
1102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  //
1112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Note that this is also a performance optimization.  Analyzing
1122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // headers many times can be expensive.
1132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (!S.getSourceManager().isInMainFile(AC.getDecl()->getLocStart()))
1142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return;
1152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  UnreachableCodeHandler UC(S);
1172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  reachable_code::FindUnreachableCode(AC, S.getPreprocessor(), UC);
1182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
1192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//===----------------------------------------------------------------------===//
1212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// Check for infinite self-recursion in functions
1222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//===----------------------------------------------------------------------===//
1232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// All blocks are in one of three states.  States are ordered so that blocks
1252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// can only move to higher states.
1262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgenum RecursiveState {
1272e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  FoundNoPath,
1282e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  FoundPath,
1292e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  FoundPathWithNoRecursiveCall
1302e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
1312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1322e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgstatic void checkForFunctionCall(Sema &S, const FunctionDecl *FD,
1332e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                 CFGBlock &Block, unsigned ExitID,
1342e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                 llvm::SmallVectorImpl<RecursiveState> &States,
1352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                 RecursiveState State) {
1362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  unsigned ID = Block.getBlockID();
1372e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // A block's state can only move to a higher state.
1392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (States[ID] >= State)
1402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return;
1412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  States[ID] = State;
1432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Found a path to the exit node without a recursive call.
1452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (ID == ExitID && State == FoundPathWithNoRecursiveCall)
1462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return;
1472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (State == FoundPathWithNoRecursiveCall) {
1492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // If the current state is FoundPathWithNoRecursiveCall, the successors
1502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // will be either FoundPathWithNoRecursiveCall or FoundPath.  To determine
1512e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // which, process all the Stmt's in this block to find any recursive calls.
1522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    for (CFGBlock::iterator I = Block.begin(), E = Block.end(); I != E; ++I) {
1532e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      if (I->getKind() != CFGElement::Statement)
1542e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        continue;
1552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1562e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      const CallExpr *CE = dyn_cast<CallExpr>(I->getAs<CFGStmt>()->getStmt());
1572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      if (CE && CE->getCalleeDecl() &&
158ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org          CE->getCalleeDecl()->getCanonicalDecl() == FD) {
1592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        // Skip function calls which are qualified with a templated class.
1612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
1622e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                CE->getCallee()->IgnoreParenImpCasts())) {
1632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          if (NestedNameSpecifier *NNS = DRE->getQualifier()) {
164ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org            if (NNS->getKind() == NestedNameSpecifier::TypeSpec &&
1652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                isa<TemplateSpecializationType>(NNS->getAsType())) {
1662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org               continue;
1672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            }
1682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          }
169ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org        }
1702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1712e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE)) {
1722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          if (isa<CXXThisExpr>(MCE->getImplicitObjectArgument()) ||
1732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org              !MCE->getMethodDecl()->isVirtual()) {
1742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            State = FoundPath;
1752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            break;
1762e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          }
1772e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        } else {
1782e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          State = FoundPath;
1792e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          break;
1802e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        }
1812e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      }
1822e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
1832e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
1842e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1852e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  for (CFGBlock::succ_iterator I = Block.succ_begin(), E = Block.succ_end();
1862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org       I != E; ++I)
1872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (*I)
1882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      checkForFunctionCall(S, FD, **I, ExitID, States, State);
1892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
1902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgstatic void checkRecursiveFunction(Sema &S, const FunctionDecl *FD,
1922e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                   const Stmt *Body,
1932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                   AnalysisDeclContext &AC) {
1942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  FD = FD->getCanonicalDecl();
1952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
1962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Only run on non-templated functions and non-templated members of
1972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // templated classes.
1982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate &&
1992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      FD->getTemplatedKind() != FunctionDecl::TK_MemberSpecialization)
2002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return;
2012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  CFG *cfg = AC.getCFG();
203ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org  if (cfg == 0) return;
2042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2052e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // If the exit block is unreachable, skip processing the function.
2062e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (cfg->getExit().pred_empty())
2072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return;
2082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Mark all nodes as FoundNoPath, then begin processing the entry block.
2102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  llvm::SmallVector<RecursiveState, 16> states(cfg->getNumBlockIDs(),
2112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                               FoundNoPath);
2122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  checkForFunctionCall(S, FD, cfg->getEntry(), cfg->getExit().getBlockID(),
2132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                       states, FoundPathWithNoRecursiveCall);
2142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Check that the exit block is reachable.  This prevents triggering the
2162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // warning on functions that do not terminate.
2172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (states[cfg->getExit().getBlockID()] == FoundPath)
2182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    S.Diag(Body->getLocStart(), diag::warn_infinite_recursive_function);
2192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
2202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//===----------------------------------------------------------------------===//
2222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// Check for missing return value.
2232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//===----------------------------------------------------------------------===//
2242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgenum ControlFlowKind {
2262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  UnknownFallThrough,
2272e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  NeverFallThrough,
2282e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  MaybeFallThrough,
229a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  AlwaysFallThrough,
230a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  NeverFallThroughOrReturn
231a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org};
232a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
233a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org/// CheckFallThrough - Check that we don't fall off the end of a
2342e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// Statement that should return a value.
2352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org///
2362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// \returns AlwaysFallThrough iff we always fall off the end of the statement,
2372e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// MaybeFallThrough iff we might or might not fall off the end,
2382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// NeverFallThroughOrReturn iff we never fall off the end of the statement or
2392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// return.  We assume NeverFallThrough iff we never fall off the end of the
2402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// statement but we may return.  We assume that functions not marked noreturn
2412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// will return.
242ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.orgstatic ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) {
2432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  CFG *cfg = AC.getCFG();
2442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (cfg == 0) return UnknownFallThrough;
2452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // The CFG leaves in dead things, and we don't want the dead code paths to
2472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // confuse us, so we mark all live things first.
2482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  llvm::BitVector live(cfg->getNumBlockIDs());
2492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  unsigned count = reachable_code::ScanReachableFromBlock(&cfg->getEntry(),
2502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                                          live);
2512e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
252a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool AddEHEdges = AC.getAddEHEdges();
253a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  if (!AddEHEdges && count != cfg->getNumBlockIDs())
254a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    // When there are things remaining dead, and we didn't add EH edges
255ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org    // from CallExprs to the catch clauses, we have to go back and
256a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    // mark them as live.
2572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
2582e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      CFGBlock &b = **I;
2592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      if (!live[b.getBlockID()]) {
2602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        if (b.pred_begin() == b.pred_end()) {
2612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator()))
2622e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            // When not adding EH edges from calls, catch clauses
2632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            // can otherwise seem dead.  Avoid noting them as dead.
2642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            count += reachable_code::ScanReachableFromBlock(&b, live);
2652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          continue;
2662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        }
2672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      }
2682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
2692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Now we know what is live, we check the live precessors of the exit block
2712e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // and look for fall through paths, being careful to ignore normal returns,
2722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // and exceptional paths.
2732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool HasLiveReturn = false;
2742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool HasFakeEdge = false;
2752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool HasPlainEdge = false;
2762e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool HasAbnormalEdge = false;
2772e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2782e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Ignore default cases that aren't likely to be reachable because all
2792e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // enums in a switch(X) have explicit case statements.
2802e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  CFGBlock::FilterOptions FO;
2812e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  FO.IgnoreDefaultsWithCoveredEnums = 1;
2822e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2832e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  for (CFGBlock::filtered_pred_iterator
2842e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org	 I = cfg->getExit().filtered_pred_start_end(FO); I.hasMore(); ++I) {
2852e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    const CFGBlock& B = **I;
2862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (!live[B.getBlockID()])
2872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      continue;
2882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // Skip blocks which contain an element marked as no-return. They don't
2902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // represent actually viable edges into the exit block, so mark them as
2912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // abnormal.
2922e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (B.hasNoReturnElement()) {
2932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      HasAbnormalEdge = true;
2942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      continue;
2952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
2962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
2972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // Destructors can appear after the 'return' in the CFG.  This is
2982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // normal.  We need to look pass the destructors for the return
2992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // statement (if it exists).
3002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend();
3012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    for ( ; ri != re ; ++ri)
3032e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      if (ri->getAs<CFGStmt>())
3042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        break;
3052e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3062e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // No more CFGElements in the block?
3072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (ri == re) {
3082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) {
3092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        HasAbnormalEdge = true;
3102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        continue;
3112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      }
3122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      // A labeled empty statement, or the entry block...
3132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      HasPlainEdge = true;
3142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      continue;
3152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
3162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    CFGStmt CS = ri->castAs<CFGStmt>();
3182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    const Stmt *S = CS.getStmt();
3192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (isa<ReturnStmt>(S)) {
3202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      HasLiveReturn = true;
3212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      continue;
3222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
3232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (isa<ObjCAtThrowStmt>(S)) {
3242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      HasFakeEdge = true;
3252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      continue;
3262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
3272e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (isa<CXXThrowExpr>(S)) {
3282e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      HasFakeEdge = true;
3292e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      continue;
3302e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
3312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (isa<MSAsmStmt>(S)) {
3322e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      // TODO: Verify this is correct.
3332e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      HasFakeEdge = true;
3342e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      HasLiveReturn = true;
3352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      continue;
3362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
3372e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (isa<CXXTryStmt>(S)) {
3382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      HasAbnormalEdge = true;
3392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      continue;
3402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
3412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (std::find(B.succ_begin(), B.succ_end(), &cfg->getExit())
3422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        == B.succ_end()) {
3432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      HasAbnormalEdge = true;
3442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      continue;
3452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
3462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    HasPlainEdge = true;
3482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
3492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (!HasPlainEdge) {
3502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (HasLiveReturn)
3512e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      return NeverFallThrough;
3522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return NeverFallThroughOrReturn;
3532e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
3542e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (HasAbnormalEdge || HasFakeEdge || HasLiveReturn)
3552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return MaybeFallThrough;
3562e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // This says AlwaysFallThrough for calls to functions that are not marked
3572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // noreturn, that don't return.  If people would like this warning to be more
3582e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // accurate, such functions should be marked as noreturn.
3592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  return AlwaysFallThrough;
3602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
3612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3622e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgnamespace {
3632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgstruct CheckFallThroughDiagnostics {
3652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  unsigned diag_MaybeFallThrough_HasNoReturn;
3662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  unsigned diag_MaybeFallThrough_ReturnsNonVoid;
3672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  unsigned diag_AlwaysFallThrough_HasNoReturn;
3682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  unsigned diag_AlwaysFallThrough_ReturnsNonVoid;
3692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  unsigned diag_NeverFallThroughOrReturn;
3702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  enum { Function, Block, Lambda } funMode;
3712e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  SourceLocation FuncLoc;
3722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) {
3742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    CheckFallThroughDiagnostics D;
3752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.FuncLoc = Func->getLocation();
3762e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.diag_MaybeFallThrough_HasNoReturn =
3772e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      diag::warn_falloff_noreturn_function;
3782e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.diag_MaybeFallThrough_ReturnsNonVoid =
3792e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      diag::warn_maybe_falloff_nonvoid_function;
3802e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.diag_AlwaysFallThrough_HasNoReturn =
3812e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      diag::warn_falloff_noreturn_function;
3822e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.diag_AlwaysFallThrough_ReturnsNonVoid =
3832e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      diag::warn_falloff_nonvoid_function;
3842e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3852e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // Don't suggest that virtual functions be marked "noreturn", since they
3862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // might be overridden by non-noreturn functions.
3872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    bool isVirtualMethod = false;
388057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func))
389057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      isVirtualMethod = Method->isVirtual();
3902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // Don't suggest that template instantiations be marked "noreturn"
3922e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    bool isTemplateInstantiation = false;
3932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func))
3942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      isTemplateInstantiation = Function->isTemplateInstantiation();
3952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
3962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (!isVirtualMethod && !isTemplateInstantiation)
3972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      D.diag_NeverFallThroughOrReturn =
3982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        diag::warn_suggest_noreturn_function;
3992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    else
4002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      D.diag_NeverFallThroughOrReturn = 0;
4012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.funMode = Function;
4031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return D;
4042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
4052e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4062e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static CheckFallThroughDiagnostics MakeForBlock() {
4072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    CheckFallThroughDiagnostics D;
4082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.diag_MaybeFallThrough_HasNoReturn =
4092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      diag::err_noreturn_block_has_return_expr;
4102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.diag_MaybeFallThrough_ReturnsNonVoid =
4111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      diag::err_maybe_falloff_nonvoid_block;
4122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.diag_AlwaysFallThrough_HasNoReturn =
4132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      diag::err_noreturn_block_has_return_expr;
41441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    D.diag_AlwaysFallThrough_ReturnsNonVoid =
415b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org      diag::err_falloff_nonvoid_block;
416bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    D.diag_NeverFallThroughOrReturn =
4172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      diag::warn_suggest_noreturn_block;
4182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.funMode = Block;
4191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return D;
4201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
4212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  static CheckFallThroughDiagnostics MakeForLambda() {
4232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    CheckFallThroughDiagnostics D;
4242bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    D.diag_MaybeFallThrough_HasNoReturn =
4252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      diag::err_noreturn_lambda_has_return_expr;
4262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.diag_MaybeFallThrough_ReturnsNonVoid =
4272bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      diag::warn_maybe_falloff_nonvoid_lambda;
4282bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    D.diag_AlwaysFallThrough_HasNoReturn =
4292e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      diag::err_noreturn_lambda_has_return_expr;
4302e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.diag_AlwaysFallThrough_ReturnsNonVoid =
4312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      diag::warn_falloff_nonvoid_lambda;
4322e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.diag_NeverFallThroughOrReturn = 0;
4332e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    D.funMode = Lambda;
4342e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return D;
4352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
4362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4372e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid,
4382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                        bool HasNoReturn) const {
4392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (funMode == Function) {
4402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      return (ReturnsVoid ||
4412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org              D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function,
4422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                   FuncLoc) == DiagnosticsEngine::Ignored)
4432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        && (!HasNoReturn ||
4442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr,
4452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                 FuncLoc) == DiagnosticsEngine::Ignored)
4462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        && (!ReturnsVoid ||
4472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
4482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org              == DiagnosticsEngine::Ignored);
4492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
4502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4512e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // For blocks / lambdas.
4522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return ReturnsVoid && !HasNoReturn
4532e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            && ((funMode == Lambda) ||
4542e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
4552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                  == DiagnosticsEngine::Ignored);
4562e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
4572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
458750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
4592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
4602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
4622e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// function that should return a value.  Check that we don't fall off the end
4632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// of a noreturn function.  We assume that functions and blocks not marked
4642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// noreturn will return.
4652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgstatic void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body,
4662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                    const BlockExpr *blkExpr,
4672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                    const CheckFallThroughDiagnostics& CD,
4682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                    AnalysisDeclContext &AC) {
4692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool ReturnsVoid = false;
4712e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool HasNoReturn = false;
4722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
4742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    ReturnsVoid = FD->getReturnType()->isVoidType();
4752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    HasNoReturn = FD->isNoReturn();
4762e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
477ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
478ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org    ReturnsVoid = MD->getReturnType()->isVoidType();
4792e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    HasNoReturn = MD->hasAttr<NoReturnAttr>();
4802e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
4812e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  else if (isa<BlockDecl>(D)) {
4822e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    QualType BlockTy = blkExpr->getType();
4831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (const FunctionType *FT =
4842e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          BlockTy->getPointeeType()->getAs<FunctionType>()) {
4852e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      if (FT->getReturnType()->isVoidType())
4862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        ReturnsVoid = true;
4872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      if (FT->getNoReturnAttr())
4882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        HasNoReturn = true;
4892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
4902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
4912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4922e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  DiagnosticsEngine &Diags = S.getDiagnostics();
4932e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Short circuit for compilation speed.
4952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
4962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      return;
4972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
4982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // FIXME: Function try block
4992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) {
5002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    switch (CheckFallThrough(AC)) {
5012e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      case UnknownFallThrough:
5022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        break;
5032e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      case MaybeFallThrough:
5053d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org        if (HasNoReturn)
5062e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          S.Diag(Compound->getRBracLoc(),
5072e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                 CD.diag_MaybeFallThrough_HasNoReturn);
5082e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        else if (!ReturnsVoid)
5092e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          S.Diag(Compound->getRBracLoc(),
5102e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                 CD.diag_MaybeFallThrough_ReturnsNonVoid);
5112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        break;
5122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      case AlwaysFallThrough:
5132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        if (HasNoReturn)
5142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          S.Diag(Compound->getRBracLoc(),
5152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                 CD.diag_AlwaysFallThrough_HasNoReturn);
5162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        else if (!ReturnsVoid)
5172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          S.Diag(Compound->getRBracLoc(),
5182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                 CD.diag_AlwaysFallThrough_ReturnsNonVoid);
5192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        break;
5202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      case NeverFallThroughOrReturn:
5212e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
5222e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
5232e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn)
5242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org              << 0 << FD;
5252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
5262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn)
5272e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org              << 1 << MD;
5282e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          } else {
5292e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn);
5302e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          }
5312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        }
5322e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        break;
5332e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      case NeverFallThrough:
5342e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        break;
5352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
5362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
5373d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org}
5382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
539ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org//===----------------------------------------------------------------------===//
5402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org// -Wuninitialized
5412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org//===----------------------------------------------------------------------===//
5422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgnamespace {
5442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// ContainsReference - A visitor class to search for references to
5452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// a particular declaration (the needle) within any evaluated component of an
5462e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// expression (recursively).
5472e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgclass ContainsReference : public EvaluatedExprVisitor<ContainsReference> {
5482e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool FoundReference;
5492e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  const DeclRefExpr *Needle;
5502e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5512e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgpublic:
5522e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  ContainsReference(ASTContext &Context, const DeclRefExpr *Needle)
5532e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    : EvaluatedExprVisitor<ContainsReference>(Context),
5542e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      FoundReference(false), Needle(Needle) {}
5552e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5562e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void VisitExpr(Expr *E) {
5572e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    // Stop evaluating if we already have a reference.
5582e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (FoundReference)
5592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      return;
5602e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5612e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    EvaluatedExprVisitor<ContainsReference>::VisitExpr(E);
5622e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
5632e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5642e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  void VisitDeclRefExpr(DeclRefExpr *E) {
5652e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (E == Needle)
5662e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      FoundReference = true;
5672e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    else
5682e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      EvaluatedExprVisitor<ContainsReference>::VisitDeclRefExpr(E);
5692e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
5702e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5712e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool doesContainReference() const { return FoundReference; }
5722e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org};
5732e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
5742e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5752e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgstatic bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
5762e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  QualType VariableTy = VD->getType().getCanonicalType();
5772e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (VariableTy->isBlockPointerType() &&
5782e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      !VD->hasAttr<BlocksAttr>()) {
5792e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization) << VD->getDeclName()
5802e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
5812e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return true;
5822e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
5832e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5842e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Don't issue a fixit if there is already an initializer.
5852e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (VD->getInit())
5862e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return false;
5872e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5882e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Don't suggest a fixit inside macros.
5892e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (VD->getLocEnd().isMacroID())
5902e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return false;
5912e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5922e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
593528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
5942e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // Suggest possible initialization (if any).
5952e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  std::string Init = S.getFixItZeroInitializerForType(VariableTy, Loc);
5962e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  if (Init.empty())
5972e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return false;
5982e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
5992e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
6002e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    << FixItHint::CreateInsertion(Loc, Init);
601528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return true;
602528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org}
603528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
6042e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// Create a fixit to remove an if-like statement, on the assumption that its
6052e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// condition is CondVal.
606528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgstatic void CreateIfFixit(Sema &S, const Stmt *If, const Stmt *Then,
607528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                          const Stmt *Else, bool CondVal,
608528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                          FixItHint &Fixit1, FixItHint &Fixit2) {
609528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  if (CondVal) {
610528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    // If condition is always true, remove all but the 'then'.
6112e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    Fixit1 = FixItHint::CreateRemoval(
6122e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        CharSourceRange::getCharRange(If->getLocStart(),
6132e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                      Then->getLocStart()));
6142e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    if (Else) {
6152e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      SourceLocation ElseKwLoc = Lexer::getLocForEndOfToken(
6162e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          Then->getLocEnd(), 0, S.getSourceManager(), S.getLangOpts());
6172e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      Fixit2 = FixItHint::CreateRemoval(
6182e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          SourceRange(ElseKwLoc, Else->getLocEnd()));
6192e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    }
6202e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  } else {
621b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    // If condition is always false, remove all but the 'else'.
622b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    if (Else)
623b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      Fixit1 = FixItHint::CreateRemoval(
6242e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org          CharSourceRange::getCharRange(If->getLocStart(),
6252e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                                        Else->getLocStart()));
6262e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    else
6272e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org      Fixit1 = FixItHint::CreateRemoval(If->getSourceRange());
6282e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  }
6292e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org}
6302e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
6312e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// DiagUninitUse -- Helper function to produce a diagnostic for an
6322e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org/// uninitialized use of a variable.
6332e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.orgstatic void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,
6342e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org                          bool IsCapturedByBlock) {
6352e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  bool Diagnosed = false;
6362e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
6372e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  switch (Use.getKind()) {
6382e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  case UninitUse::Always:
6392e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    S.Diag(Use.getUser()->getLocStart(), diag::warn_uninit_var)
6402e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        << VD->getDeclName() << IsCapturedByBlock
6412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org        << Use.getUser()->getSourceRange();
6422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org    return;
6432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
6442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  case UninitUse::AfterDecl:
6452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  case UninitUse::AfterCall:
646    S.Diag(VD->getLocation(), diag::warn_sometimes_uninit_var)
647      << VD->getDeclName() << IsCapturedByBlock
648      << (Use.getKind() == UninitUse::AfterDecl ? 4 : 5)
649      << const_cast<DeclContext*>(VD->getLexicalDeclContext())
650      << VD->getSourceRange();
651    S.Diag(Use.getUser()->getLocStart(), diag::note_uninit_var_use)
652      << IsCapturedByBlock << Use.getUser()->getSourceRange();
653    return;
654
655  case UninitUse::Maybe:
656  case UninitUse::Sometimes:
657    // Carry on to report sometimes-uninitialized branches, if possible,
658    // or a 'may be used uninitialized' diagnostic otherwise.
659    break;
660  }
661
662  // Diagnose each branch which leads to a sometimes-uninitialized use.
663  for (UninitUse::branch_iterator I = Use.branch_begin(), E = Use.branch_end();
664       I != E; ++I) {
665    assert(Use.getKind() == UninitUse::Sometimes);
666
667    const Expr *User = Use.getUser();
668    const Stmt *Term = I->Terminator;
669
670    // Information used when building the diagnostic.
671    unsigned DiagKind;
672    StringRef Str;
673    SourceRange Range;
674
675    // FixIts to suppress the diagnostic by removing the dead condition.
676    // For all binary terminators, branch 0 is taken if the condition is true,
677    // and branch 1 is taken if the condition is false.
678    int RemoveDiagKind = -1;
679    const char *FixitStr =
680        S.getLangOpts().CPlusPlus ? (I->Output ? "true" : "false")
681                                  : (I->Output ? "1" : "0");
682    FixItHint Fixit1, Fixit2;
683
684    switch (Term ? Term->getStmtClass() : Stmt::DeclStmtClass) {
685    default:
686      // Don't know how to report this. Just fall back to 'may be used
687      // uninitialized'. FIXME: Can this happen?
688      continue;
689
690    // "condition is true / condition is false".
691    case Stmt::IfStmtClass: {
692      const IfStmt *IS = cast<IfStmt>(Term);
693      DiagKind = 0;
694      Str = "if";
695      Range = IS->getCond()->getSourceRange();
696      RemoveDiagKind = 0;
697      CreateIfFixit(S, IS, IS->getThen(), IS->getElse(),
698                    I->Output, Fixit1, Fixit2);
699      break;
700    }
701    case Stmt::ConditionalOperatorClass: {
702      const ConditionalOperator *CO = cast<ConditionalOperator>(Term);
703      DiagKind = 0;
704      Str = "?:";
705      Range = CO->getCond()->getSourceRange();
706      RemoveDiagKind = 0;
707      CreateIfFixit(S, CO, CO->getTrueExpr(), CO->getFalseExpr(),
708                    I->Output, Fixit1, Fixit2);
709      break;
710    }
711    case Stmt::BinaryOperatorClass: {
712      const BinaryOperator *BO = cast<BinaryOperator>(Term);
713      if (!BO->isLogicalOp())
714        continue;
715      DiagKind = 0;
716      Str = BO->getOpcodeStr();
717      Range = BO->getLHS()->getSourceRange();
718      RemoveDiagKind = 0;
719      if ((BO->getOpcode() == BO_LAnd && I->Output) ||
720          (BO->getOpcode() == BO_LOr && !I->Output))
721        // true && y -> y, false || y -> y.
722        Fixit1 = FixItHint::CreateRemoval(SourceRange(BO->getLocStart(),
723                                                      BO->getOperatorLoc()));
724      else
725        // false && y -> false, true || y -> true.
726        Fixit1 = FixItHint::CreateReplacement(BO->getSourceRange(), FixitStr);
727      break;
728    }
729
730    // "loop is entered / loop is exited".
731    case Stmt::WhileStmtClass:
732      DiagKind = 1;
733      Str = "while";
734      Range = cast<WhileStmt>(Term)->getCond()->getSourceRange();
735      RemoveDiagKind = 1;
736      Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
737      break;
738    case Stmt::ForStmtClass:
739      DiagKind = 1;
740      Str = "for";
741      Range = cast<ForStmt>(Term)->getCond()->getSourceRange();
742      RemoveDiagKind = 1;
743      if (I->Output)
744        Fixit1 = FixItHint::CreateRemoval(Range);
745      else
746        Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
747      break;
748    case Stmt::CXXForRangeStmtClass:
749      if (I->Output == 1) {
750        // The use occurs if a range-based for loop's body never executes.
751        // That may be impossible, and there's no syntactic fix for this,
752        // so treat it as a 'may be uninitialized' case.
753        continue;
754      }
755      DiagKind = 1;
756      Str = "for";
757      Range = cast<CXXForRangeStmt>(Term)->getRangeInit()->getSourceRange();
758      break;
759
760    // "condition is true / loop is exited".
761    case Stmt::DoStmtClass:
762      DiagKind = 2;
763      Str = "do";
764      Range = cast<DoStmt>(Term)->getCond()->getSourceRange();
765      RemoveDiagKind = 1;
766      Fixit1 = FixItHint::CreateReplacement(Range, FixitStr);
767      break;
768
769    // "switch case is taken".
770    case Stmt::CaseStmtClass:
771      DiagKind = 3;
772      Str = "case";
773      Range = cast<CaseStmt>(Term)->getLHS()->getSourceRange();
774      break;
775    case Stmt::DefaultStmtClass:
776      DiagKind = 3;
777      Str = "default";
778      Range = cast<DefaultStmt>(Term)->getDefaultLoc();
779      break;
780    }
781
782    S.Diag(Range.getBegin(), diag::warn_sometimes_uninit_var)
783      << VD->getDeclName() << IsCapturedByBlock << DiagKind
784      << Str << I->Output << Range;
785    S.Diag(User->getLocStart(), diag::note_uninit_var_use)
786      << IsCapturedByBlock << User->getSourceRange();
787    if (RemoveDiagKind != -1)
788      S.Diag(Fixit1.RemoveRange.getBegin(), diag::note_uninit_fixit_remove_cond)
789        << RemoveDiagKind << Str << I->Output << Fixit1 << Fixit2;
790
791    Diagnosed = true;
792  }
793
794  if (!Diagnosed)
795    S.Diag(Use.getUser()->getLocStart(), diag::warn_maybe_uninit_var)
796        << VD->getDeclName() << IsCapturedByBlock
797        << Use.getUser()->getSourceRange();
798}
799
800/// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an
801/// uninitialized variable. This manages the different forms of diagnostic
802/// emitted for particular types of uses. Returns true if the use was diagnosed
803/// as a warning. If a particular use is one we omit warnings for, returns
804/// false.
805static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
806                                     const UninitUse &Use,
807                                     bool alwaysReportSelfInit = false) {
808
809  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Use.getUser())) {
810    // Inspect the initializer of the variable declaration which is
811    // being referenced prior to its initialization. We emit
812    // specialized diagnostics for self-initialization, and we
813    // specifically avoid warning about self references which take the
814    // form of:
815    //
816    //   int x = x;
817    //
818    // This is used to indicate to GCC that 'x' is intentionally left
819    // uninitialized. Proven code paths which access 'x' in
820    // an uninitialized state after this will still warn.
821    if (const Expr *Initializer = VD->getInit()) {
822      if (!alwaysReportSelfInit && DRE == Initializer->IgnoreParenImpCasts())
823        return false;
824
825      ContainsReference CR(S.Context, DRE);
826      CR.Visit(const_cast<Expr*>(Initializer));
827      if (CR.doesContainReference()) {
828        S.Diag(DRE->getLocStart(),
829               diag::warn_uninit_self_reference_in_init)
830          << VD->getDeclName() << VD->getLocation() << DRE->getSourceRange();
831        return true;
832      }
833    }
834
835    DiagUninitUse(S, VD, Use, false);
836  } else {
837    const BlockExpr *BE = cast<BlockExpr>(Use.getUser());
838    if (VD->getType()->isBlockPointerType() && !VD->hasAttr<BlocksAttr>())
839      S.Diag(BE->getLocStart(),
840             diag::warn_uninit_byref_blockvar_captured_by_block)
841        << VD->getDeclName();
842    else
843      DiagUninitUse(S, VD, Use, true);
844  }
845
846  // Report where the variable was declared when the use wasn't within
847  // the initializer of that declaration & we didn't already suggest
848  // an initialization fixit.
849  if (!SuggestInitializationFixit(S, VD))
850    S.Diag(VD->getLocStart(), diag::note_uninit_var_def)
851      << VD->getDeclName();
852
853  return true;
854}
855
856namespace {
857  class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> {
858  public:
859    FallthroughMapper(Sema &S)
860      : FoundSwitchStatements(false),
861        S(S) {
862    }
863
864    bool foundSwitchStatements() const { return FoundSwitchStatements; }
865
866    void markFallthroughVisited(const AttributedStmt *Stmt) {
867      bool Found = FallthroughStmts.erase(Stmt);
868      assert(Found);
869      (void)Found;
870    }
871
872    typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts;
873
874    const AttrStmts &getFallthroughStmts() const {
875      return FallthroughStmts;
876    }
877
878    void fillReachableBlocks(CFG *Cfg) {
879      assert(ReachableBlocks.empty() && "ReachableBlocks already filled");
880      std::deque<const CFGBlock *> BlockQueue;
881
882      ReachableBlocks.insert(&Cfg->getEntry());
883      BlockQueue.push_back(&Cfg->getEntry());
884      // Mark all case blocks reachable to avoid problems with switching on
885      // constants, covered enums, etc.
886      // These blocks can contain fall-through annotations, and we don't want to
887      // issue a warn_fallthrough_attr_unreachable for them.
888      for (CFG::iterator I = Cfg->begin(), E = Cfg->end(); I != E; ++I) {
889        const CFGBlock *B = *I;
890        const Stmt *L = B->getLabel();
891        if (L && isa<SwitchCase>(L) && ReachableBlocks.insert(B))
892          BlockQueue.push_back(B);
893      }
894
895      while (!BlockQueue.empty()) {
896        const CFGBlock *P = BlockQueue.front();
897        BlockQueue.pop_front();
898        for (CFGBlock::const_succ_iterator I = P->succ_begin(),
899                                           E = P->succ_end();
900             I != E; ++I) {
901          if (*I && ReachableBlocks.insert(*I))
902            BlockQueue.push_back(*I);
903        }
904      }
905    }
906
907    bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) {
908      assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
909
910      int UnannotatedCnt = 0;
911      AnnotatedCnt = 0;
912
913      std::deque<const CFGBlock*> BlockQueue;
914
915      std::copy(B.pred_begin(), B.pred_end(), std::back_inserter(BlockQueue));
916
917      while (!BlockQueue.empty()) {
918        const CFGBlock *P = BlockQueue.front();
919        BlockQueue.pop_front();
920        if (!P) continue;
921
922        const Stmt *Term = P->getTerminator();
923        if (Term && isa<SwitchStmt>(Term))
924          continue; // Switch statement, good.
925
926        const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel());
927        if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end())
928          continue; // Previous case label has no statements, good.
929
930        const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel());
931        if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end())
932          continue; // Case label is preceded with a normal label, good.
933
934        if (!ReachableBlocks.count(P)) {
935          for (CFGBlock::const_reverse_iterator ElemIt = P->rbegin(),
936                                                ElemEnd = P->rend();
937               ElemIt != ElemEnd; ++ElemIt) {
938            if (Optional<CFGStmt> CS = ElemIt->getAs<CFGStmt>()) {
939              if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) {
940                S.Diag(AS->getLocStart(),
941                       diag::warn_fallthrough_attr_unreachable);
942                markFallthroughVisited(AS);
943                ++AnnotatedCnt;
944                break;
945              }
946              // Don't care about other unreachable statements.
947            }
948          }
949          // If there are no unreachable statements, this may be a special
950          // case in CFG:
951          // case X: {
952          //    A a;  // A has a destructor.
953          //    break;
954          // }
955          // // <<<< This place is represented by a 'hanging' CFG block.
956          // case Y:
957          continue;
958        }
959
960        const Stmt *LastStmt = getLastStmt(*P);
961        if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) {
962          markFallthroughVisited(AS);
963          ++AnnotatedCnt;
964          continue; // Fallthrough annotation, good.
965        }
966
967        if (!LastStmt) { // This block contains no executable statements.
968          // Traverse its predecessors.
969          std::copy(P->pred_begin(), P->pred_end(),
970                    std::back_inserter(BlockQueue));
971          continue;
972        }
973
974        ++UnannotatedCnt;
975      }
976      return !!UnannotatedCnt;
977    }
978
979    // RecursiveASTVisitor setup.
980    bool shouldWalkTypesOfTypeLocs() const { return false; }
981
982    bool VisitAttributedStmt(AttributedStmt *S) {
983      if (asFallThroughAttr(S))
984        FallthroughStmts.insert(S);
985      return true;
986    }
987
988    bool VisitSwitchStmt(SwitchStmt *S) {
989      FoundSwitchStatements = true;
990      return true;
991    }
992
993    // We don't want to traverse local type declarations. We analyze their
994    // methods separately.
995    bool TraverseDecl(Decl *D) { return true; }
996
997  private:
998
999    static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
1000      if (const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(S)) {
1001        if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
1002          return AS;
1003      }
1004      return 0;
1005    }
1006
1007    static const Stmt *getLastStmt(const CFGBlock &B) {
1008      if (const Stmt *Term = B.getTerminator())
1009        return Term;
1010      for (CFGBlock::const_reverse_iterator ElemIt = B.rbegin(),
1011                                            ElemEnd = B.rend();
1012                                            ElemIt != ElemEnd; ++ElemIt) {
1013        if (Optional<CFGStmt> CS = ElemIt->getAs<CFGStmt>())
1014          return CS->getStmt();
1015      }
1016      // Workaround to detect a statement thrown out by CFGBuilder:
1017      //   case X: {} case Y:
1018      //   case X: ; case Y:
1019      if (const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(B.getLabel()))
1020        if (!isa<SwitchCase>(SW->getSubStmt()))
1021          return SW->getSubStmt();
1022
1023      return 0;
1024    }
1025
1026    bool FoundSwitchStatements;
1027    AttrStmts FallthroughStmts;
1028    Sema &S;
1029    llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
1030  };
1031}
1032
1033static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC,
1034                                            bool PerFunction) {
1035  // Only perform this analysis when using C++11.  There is no good workflow
1036  // for this warning when not using C++11.  There is no good way to silence
1037  // the warning (no attribute is available) unless we are using C++11's support
1038  // for generalized attributes.  Once could use pragmas to silence the warning,
1039  // but as a general solution that is gross and not in the spirit of this
1040  // warning.
1041  //
1042  // NOTE: This an intermediate solution.  There are on-going discussions on
1043  // how to properly support this warning outside of C++11 with an annotation.
1044  if (!AC.getASTContext().getLangOpts().CPlusPlus11)
1045    return;
1046
1047  FallthroughMapper FM(S);
1048  FM.TraverseStmt(AC.getBody());
1049
1050  if (!FM.foundSwitchStatements())
1051    return;
1052
1053  if (PerFunction && FM.getFallthroughStmts().empty())
1054    return;
1055
1056  CFG *Cfg = AC.getCFG();
1057
1058  if (!Cfg)
1059    return;
1060
1061  FM.fillReachableBlocks(Cfg);
1062
1063  for (CFG::reverse_iterator I = Cfg->rbegin(), E = Cfg->rend(); I != E; ++I) {
1064    const CFGBlock *B = *I;
1065    const Stmt *Label = B->getLabel();
1066
1067    if (!Label || !isa<SwitchCase>(Label))
1068      continue;
1069
1070    int AnnotatedCnt;
1071
1072    if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt))
1073      continue;
1074
1075    S.Diag(Label->getLocStart(),
1076        PerFunction ? diag::warn_unannotated_fallthrough_per_function
1077                    : diag::warn_unannotated_fallthrough);
1078
1079    if (!AnnotatedCnt) {
1080      SourceLocation L = Label->getLocStart();
1081      if (L.isMacroID())
1082        continue;
1083      if (S.getLangOpts().CPlusPlus11) {
1084        const Stmt *Term = B->getTerminator();
1085        // Skip empty cases.
1086        while (B->empty() && !Term && B->succ_size() == 1) {
1087          B = *B->succ_begin();
1088          Term = B->getTerminator();
1089        }
1090        if (!(B->empty() && Term && isa<BreakStmt>(Term))) {
1091          Preprocessor &PP = S.getPreprocessor();
1092          TokenValue Tokens[] = {
1093            tok::l_square, tok::l_square, PP.getIdentifierInfo("clang"),
1094            tok::coloncolon, PP.getIdentifierInfo("fallthrough"),
1095            tok::r_square, tok::r_square
1096          };
1097          StringRef AnnotationSpelling = "[[clang::fallthrough]]";
1098          StringRef MacroName = PP.getLastMacroWithSpelling(L, Tokens);
1099          if (!MacroName.empty())
1100            AnnotationSpelling = MacroName;
1101          SmallString<64> TextToInsert(AnnotationSpelling);
1102          TextToInsert += "; ";
1103          S.Diag(L, diag::note_insert_fallthrough_fixit) <<
1104              AnnotationSpelling <<
1105              FixItHint::CreateInsertion(L, TextToInsert);
1106        }
1107      }
1108      S.Diag(L, diag::note_insert_break_fixit) <<
1109        FixItHint::CreateInsertion(L, "break; ");
1110    }
1111  }
1112
1113  const FallthroughMapper::AttrStmts &Fallthroughs = FM.getFallthroughStmts();
1114  for (FallthroughMapper::AttrStmts::const_iterator I = Fallthroughs.begin(),
1115                                                    E = Fallthroughs.end();
1116                                                    I != E; ++I) {
1117    S.Diag((*I)->getLocStart(), diag::warn_fallthrough_attr_invalid_placement);
1118  }
1119
1120}
1121
1122static bool isInLoop(const ASTContext &Ctx, const ParentMap &PM,
1123                     const Stmt *S) {
1124  assert(S);
1125
1126  do {
1127    switch (S->getStmtClass()) {
1128    case Stmt::ForStmtClass:
1129    case Stmt::WhileStmtClass:
1130    case Stmt::CXXForRangeStmtClass:
1131    case Stmt::ObjCForCollectionStmtClass:
1132      return true;
1133    case Stmt::DoStmtClass: {
1134      const Expr *Cond = cast<DoStmt>(S)->getCond();
1135      llvm::APSInt Val;
1136      if (!Cond->EvaluateAsInt(Val, Ctx))
1137        return true;
1138      return Val.getBoolValue();
1139    }
1140    default:
1141      break;
1142    }
1143  } while ((S = PM.getParent(S)));
1144
1145  return false;
1146}
1147
1148
1149static void diagnoseRepeatedUseOfWeak(Sema &S,
1150                                      const sema::FunctionScopeInfo *CurFn,
1151                                      const Decl *D,
1152                                      const ParentMap &PM) {
1153  typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy;
1154  typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap;
1155  typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector;
1156  typedef std::pair<const Stmt *, WeakObjectUseMap::const_iterator>
1157  StmtUsesPair;
1158
1159  ASTContext &Ctx = S.getASTContext();
1160
1161  const WeakObjectUseMap &WeakMap = CurFn->getWeakObjectUses();
1162
1163  // Extract all weak objects that are referenced more than once.
1164  SmallVector<StmtUsesPair, 8> UsesByStmt;
1165  for (WeakObjectUseMap::const_iterator I = WeakMap.begin(), E = WeakMap.end();
1166       I != E; ++I) {
1167    const WeakUseVector &Uses = I->second;
1168
1169    // Find the first read of the weak object.
1170    WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end();
1171    for ( ; UI != UE; ++UI) {
1172      if (UI->isUnsafe())
1173        break;
1174    }
1175
1176    // If there were only writes to this object, don't warn.
1177    if (UI == UE)
1178      continue;
1179
1180    // If there was only one read, followed by any number of writes, and the
1181    // read is not within a loop, don't warn. Additionally, don't warn in a
1182    // loop if the base object is a local variable -- local variables are often
1183    // changed in loops.
1184    if (UI == Uses.begin()) {
1185      WeakUseVector::const_iterator UI2 = UI;
1186      for (++UI2; UI2 != UE; ++UI2)
1187        if (UI2->isUnsafe())
1188          break;
1189
1190      if (UI2 == UE) {
1191        if (!isInLoop(Ctx, PM, UI->getUseExpr()))
1192          continue;
1193
1194        const WeakObjectProfileTy &Profile = I->first;
1195        if (!Profile.isExactProfile())
1196          continue;
1197
1198        const NamedDecl *Base = Profile.getBase();
1199        if (!Base)
1200          Base = Profile.getProperty();
1201        assert(Base && "A profile always has a base or property.");
1202
1203        if (const VarDecl *BaseVar = dyn_cast<VarDecl>(Base))
1204          if (BaseVar->hasLocalStorage() && !isa<ParmVarDecl>(Base))
1205            continue;
1206      }
1207    }
1208
1209    UsesByStmt.push_back(StmtUsesPair(UI->getUseExpr(), I));
1210  }
1211
1212  if (UsesByStmt.empty())
1213    return;
1214
1215  // Sort by first use so that we emit the warnings in a deterministic order.
1216  SourceManager &SM = S.getSourceManager();
1217  std::sort(UsesByStmt.begin(), UsesByStmt.end(),
1218            [&SM](const StmtUsesPair &LHS, const StmtUsesPair &RHS) {
1219    return SM.isBeforeInTranslationUnit(LHS.first->getLocStart(),
1220                                        RHS.first->getLocStart());
1221  });
1222
1223  // Classify the current code body for better warning text.
1224  // This enum should stay in sync with the cases in
1225  // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.
1226  // FIXME: Should we use a common classification enum and the same set of
1227  // possibilities all throughout Sema?
1228  enum {
1229    Function,
1230    Method,
1231    Block,
1232    Lambda
1233  } FunctionKind;
1234
1235  if (isa<sema::BlockScopeInfo>(CurFn))
1236    FunctionKind = Block;
1237  else if (isa<sema::LambdaScopeInfo>(CurFn))
1238    FunctionKind = Lambda;
1239  else if (isa<ObjCMethodDecl>(D))
1240    FunctionKind = Method;
1241  else
1242    FunctionKind = Function;
1243
1244  // Iterate through the sorted problems and emit warnings for each.
1245  for (SmallVectorImpl<StmtUsesPair>::const_iterator I = UsesByStmt.begin(),
1246                                                     E = UsesByStmt.end();
1247       I != E; ++I) {
1248    const Stmt *FirstRead = I->first;
1249    const WeakObjectProfileTy &Key = I->second->first;
1250    const WeakUseVector &Uses = I->second->second;
1251
1252    // For complicated expressions like 'a.b.c' and 'x.b.c', WeakObjectProfileTy
1253    // may not contain enough information to determine that these are different
1254    // properties. We can only be 100% sure of a repeated use in certain cases,
1255    // and we adjust the diagnostic kind accordingly so that the less certain
1256    // case can be turned off if it is too noisy.
1257    unsigned DiagKind;
1258    if (Key.isExactProfile())
1259      DiagKind = diag::warn_arc_repeated_use_of_weak;
1260    else
1261      DiagKind = diag::warn_arc_possible_repeated_use_of_weak;
1262
1263    // Classify the weak object being accessed for better warning text.
1264    // This enum should stay in sync with the cases in
1265    // warn_arc_repeated_use_of_weak and warn_arc_possible_repeated_use_of_weak.
1266    enum {
1267      Variable,
1268      Property,
1269      ImplicitProperty,
1270      Ivar
1271    } ObjectKind;
1272
1273    const NamedDecl *D = Key.getProperty();
1274    if (isa<VarDecl>(D))
1275      ObjectKind = Variable;
1276    else if (isa<ObjCPropertyDecl>(D))
1277      ObjectKind = Property;
1278    else if (isa<ObjCMethodDecl>(D))
1279      ObjectKind = ImplicitProperty;
1280    else if (isa<ObjCIvarDecl>(D))
1281      ObjectKind = Ivar;
1282    else
1283      llvm_unreachable("Unexpected weak object kind!");
1284
1285    // Show the first time the object was read.
1286    S.Diag(FirstRead->getLocStart(), DiagKind)
1287      << int(ObjectKind) << D << int(FunctionKind)
1288      << FirstRead->getSourceRange();
1289
1290    // Print all the other accesses as notes.
1291    for (WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end();
1292         UI != UE; ++UI) {
1293      if (UI->getUseExpr() == FirstRead)
1294        continue;
1295      S.Diag(UI->getUseExpr()->getLocStart(),
1296             diag::note_arc_weak_also_accessed_here)
1297        << UI->getUseExpr()->getSourceRange();
1298    }
1299  }
1300}
1301
1302namespace {
1303class UninitValsDiagReporter : public UninitVariablesHandler {
1304  Sema &S;
1305  typedef SmallVector<UninitUse, 2> UsesVec;
1306  typedef llvm::PointerIntPair<UsesVec *, 1, bool> MappedType;
1307  // Prefer using MapVector to DenseMap, so that iteration order will be
1308  // the same as insertion order. This is needed to obtain a deterministic
1309  // order of diagnostics when calling flushDiagnostics().
1310  typedef llvm::MapVector<const VarDecl *, MappedType> UsesMap;
1311  UsesMap *uses;
1312
1313public:
1314  UninitValsDiagReporter(Sema &S) : S(S), uses(0) {}
1315  ~UninitValsDiagReporter() {
1316    flushDiagnostics();
1317  }
1318
1319  MappedType &getUses(const VarDecl *vd) {
1320    if (!uses)
1321      uses = new UsesMap();
1322
1323    MappedType &V = (*uses)[vd];
1324    if (!V.getPointer())
1325      V.setPointer(new UsesVec());
1326
1327    return V;
1328  }
1329
1330  void handleUseOfUninitVariable(const VarDecl *vd,
1331                                 const UninitUse &use) override {
1332    getUses(vd).getPointer()->push_back(use);
1333  }
1334
1335  void handleSelfInit(const VarDecl *vd) override {
1336    getUses(vd).setInt(true);
1337  }
1338
1339  void flushDiagnostics() {
1340    if (!uses)
1341      return;
1342
1343    for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) {
1344      const VarDecl *vd = i->first;
1345      const MappedType &V = i->second;
1346
1347      UsesVec *vec = V.getPointer();
1348      bool hasSelfInit = V.getInt();
1349
1350      // Specially handle the case where we have uses of an uninitialized
1351      // variable, but the root cause is an idiomatic self-init.  We want
1352      // to report the diagnostic at the self-init since that is the root cause.
1353      if (!vec->empty() && hasSelfInit && hasAlwaysUninitializedUse(vec))
1354        DiagnoseUninitializedUse(S, vd,
1355                                 UninitUse(vd->getInit()->IgnoreParenCasts(),
1356                                           /* isAlwaysUninit */ true),
1357                                 /* alwaysReportSelfInit */ true);
1358      else {
1359        // Sort the uses by their SourceLocations.  While not strictly
1360        // guaranteed to produce them in line/column order, this will provide
1361        // a stable ordering.
1362        std::sort(vec->begin(), vec->end(),
1363                  [](const UninitUse &a, const UninitUse &b) {
1364          // Prefer a more confident report over a less confident one.
1365          if (a.getKind() != b.getKind())
1366            return a.getKind() > b.getKind();
1367          return a.getUser()->getLocStart() < b.getUser()->getLocStart();
1368        });
1369
1370        for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve;
1371             ++vi) {
1372          // If we have self-init, downgrade all uses to 'may be uninitialized'.
1373          UninitUse Use = hasSelfInit ? UninitUse(vi->getUser(), false) : *vi;
1374
1375          if (DiagnoseUninitializedUse(S, vd, Use))
1376            // Skip further diagnostics for this variable. We try to warn only
1377            // on the first point at which a variable is used uninitialized.
1378            break;
1379        }
1380      }
1381
1382      // Release the uses vector.
1383      delete vec;
1384    }
1385    delete uses;
1386  }
1387
1388private:
1389  static bool hasAlwaysUninitializedUse(const UsesVec* vec) {
1390  for (UsesVec::const_iterator i = vec->begin(), e = vec->end(); i != e; ++i) {
1391    if (i->getKind() == UninitUse::Always ||
1392        i->getKind() == UninitUse::AfterCall ||
1393        i->getKind() == UninitUse::AfterDecl) {
1394      return true;
1395    }
1396  }
1397  return false;
1398}
1399};
1400}
1401
1402namespace clang {
1403namespace {
1404typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes;
1405typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;
1406typedef std::list<DelayedDiag> DiagList;
1407
1408struct SortDiagBySourceLocation {
1409  SourceManager &SM;
1410  SortDiagBySourceLocation(SourceManager &SM) : SM(SM) {}
1411
1412  bool operator()(const DelayedDiag &left, const DelayedDiag &right) {
1413    // Although this call will be slow, this is only called when outputting
1414    // multiple warnings.
1415    return SM.isBeforeInTranslationUnit(left.first.first, right.first.first);
1416  }
1417};
1418}}
1419
1420//===----------------------------------------------------------------------===//
1421// -Wthread-safety
1422//===----------------------------------------------------------------------===//
1423namespace clang {
1424namespace thread_safety {
1425namespace {
1426class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {
1427  Sema &S;
1428  DiagList Warnings;
1429  SourceLocation FunLocation, FunEndLocation;
1430
1431  // Helper functions
1432  void warnLockMismatch(unsigned DiagID, StringRef Kind, Name LockName,
1433                        SourceLocation Loc) {
1434    // Gracefully handle rare cases when the analysis can't get a more
1435    // precise source location.
1436    if (!Loc.isValid())
1437      Loc = FunLocation;
1438    PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName);
1439    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1440  }
1441
1442 public:
1443  ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL)
1444    : S(S), FunLocation(FL), FunEndLocation(FEL) {}
1445
1446  /// \brief Emit all buffered diagnostics in order of sourcelocation.
1447  /// We need to output diagnostics produced while iterating through
1448  /// the lockset in deterministic order, so this function orders diagnostics
1449  /// and outputs them.
1450  void emitDiagnostics() {
1451    Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));
1452    for (DiagList::iterator I = Warnings.begin(), E = Warnings.end();
1453         I != E; ++I) {
1454      S.Diag(I->first.first, I->first.second);
1455      const OptionalNotes &Notes = I->second;
1456      for (unsigned NoteI = 0, NoteN = Notes.size(); NoteI != NoteN; ++NoteI)
1457        S.Diag(Notes[NoteI].first, Notes[NoteI].second);
1458    }
1459  }
1460
1461  void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) override {
1462    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_cannot_resolve_lock)
1463                                         << Loc);
1464    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1465  }
1466  void handleUnmatchedUnlock(StringRef Kind, Name LockName,
1467                             SourceLocation Loc) override {
1468    warnLockMismatch(diag::warn_unlock_but_no_lock, Kind, LockName, Loc);
1469  }
1470  void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
1471                                 LockKind Expected, LockKind Received,
1472                                 SourceLocation Loc) override {
1473    if (Loc.isInvalid())
1474      Loc = FunLocation;
1475    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_kind_mismatch)
1476                                         << Kind << LockName << Received
1477                                         << Expected);
1478    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1479  }
1480  void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override {
1481    warnLockMismatch(diag::warn_double_lock, Kind, LockName, Loc);
1482  }
1483
1484  void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
1485                                 SourceLocation LocLocked,
1486                                 SourceLocation LocEndOfScope,
1487                                 LockErrorKind LEK) override {
1488    unsigned DiagID = 0;
1489    switch (LEK) {
1490      case LEK_LockedSomePredecessors:
1491        DiagID = diag::warn_lock_some_predecessors;
1492        break;
1493      case LEK_LockedSomeLoopIterations:
1494        DiagID = diag::warn_expecting_lock_held_on_loop;
1495        break;
1496      case LEK_LockedAtEndOfFunction:
1497        DiagID = diag::warn_no_unlock;
1498        break;
1499      case LEK_NotLockedAtEndOfFunction:
1500        DiagID = diag::warn_expecting_locked;
1501        break;
1502    }
1503    if (LocEndOfScope.isInvalid())
1504      LocEndOfScope = FunEndLocation;
1505
1506    PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << Kind
1507                                                               << LockName);
1508    if (LocLocked.isValid()) {
1509      PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here)
1510                                              << Kind);
1511      Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
1512      return;
1513    }
1514    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1515  }
1516
1517  void handleExclusiveAndShared(StringRef Kind, Name LockName,
1518                                SourceLocation Loc1,
1519                                SourceLocation Loc2) override {
1520    PartialDiagnosticAt Warning(Loc1,
1521                                S.PDiag(diag::warn_lock_exclusive_and_shared)
1522                                    << Kind << LockName);
1523    PartialDiagnosticAt Note(Loc2, S.PDiag(diag::note_lock_exclusive_and_shared)
1524                                       << Kind << LockName);
1525    Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
1526  }
1527
1528  void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
1529                         ProtectedOperationKind POK, AccessKind AK,
1530                         SourceLocation Loc) override {
1531    assert((POK == POK_VarAccess || POK == POK_VarDereference) &&
1532           "Only works for variables");
1533    unsigned DiagID = POK == POK_VarAccess?
1534                        diag::warn_variable_requires_any_lock:
1535                        diag::warn_var_deref_requires_any_lock;
1536    PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
1537      << D->getNameAsString() << getLockKindFromAccessKind(AK));
1538    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1539  }
1540
1541  void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
1542                          ProtectedOperationKind POK, Name LockName,
1543                          LockKind LK, SourceLocation Loc,
1544                          Name *PossibleMatch) override {
1545    unsigned DiagID = 0;
1546    if (PossibleMatch) {
1547      switch (POK) {
1548        case POK_VarAccess:
1549          DiagID = diag::warn_variable_requires_lock_precise;
1550          break;
1551        case POK_VarDereference:
1552          DiagID = diag::warn_var_deref_requires_lock_precise;
1553          break;
1554        case POK_FunctionCall:
1555          DiagID = diag::warn_fun_requires_lock_precise;
1556          break;
1557      }
1558      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
1559                                                       << D->getNameAsString()
1560                                                       << LockName << LK);
1561      PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match)
1562                                        << *PossibleMatch);
1563      Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
1564    } else {
1565      switch (POK) {
1566        case POK_VarAccess:
1567          DiagID = diag::warn_variable_requires_lock;
1568          break;
1569        case POK_VarDereference:
1570          DiagID = diag::warn_var_deref_requires_lock;
1571          break;
1572        case POK_FunctionCall:
1573          DiagID = diag::warn_fun_requires_lock;
1574          break;
1575      }
1576      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
1577                                                       << D->getNameAsString()
1578                                                       << LockName << LK);
1579      Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1580    }
1581  }
1582
1583  void handleFunExcludesLock(StringRef Kind, Name FunName, Name LockName,
1584                             SourceLocation Loc) override {
1585    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_fun_excludes_mutex)
1586                                         << Kind << FunName << LockName);
1587    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1588  }
1589};
1590}
1591}
1592}
1593
1594//===----------------------------------------------------------------------===//
1595// -Wconsumed
1596//===----------------------------------------------------------------------===//
1597
1598namespace clang {
1599namespace consumed {
1600namespace {
1601class ConsumedWarningsHandler : public ConsumedWarningsHandlerBase {
1602
1603  Sema &S;
1604  DiagList Warnings;
1605
1606public:
1607
1608  ConsumedWarningsHandler(Sema &S) : S(S) {}
1609
1610  void emitDiagnostics() override {
1611    Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));
1612
1613    for (DiagList::iterator I = Warnings.begin(), E = Warnings.end();
1614         I != E; ++I) {
1615
1616      const OptionalNotes &Notes = I->second;
1617      S.Diag(I->first.first, I->first.second);
1618
1619      for (unsigned NoteI = 0, NoteN = Notes.size(); NoteI != NoteN; ++NoteI) {
1620        S.Diag(Notes[NoteI].first, Notes[NoteI].second);
1621      }
1622    }
1623  }
1624
1625  void warnLoopStateMismatch(SourceLocation Loc,
1626                             StringRef VariableName) override {
1627    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch) <<
1628      VariableName);
1629
1630    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1631  }
1632
1633  void warnParamReturnTypestateMismatch(SourceLocation Loc,
1634                                        StringRef VariableName,
1635                                        StringRef ExpectedState,
1636                                        StringRef ObservedState) override {
1637
1638    PartialDiagnosticAt Warning(Loc, S.PDiag(
1639      diag::warn_param_return_typestate_mismatch) << VariableName <<
1640        ExpectedState << ObservedState);
1641
1642    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1643  }
1644
1645  void warnParamTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
1646                                  StringRef ObservedState) override {
1647
1648    PartialDiagnosticAt Warning(Loc, S.PDiag(
1649      diag::warn_param_typestate_mismatch) << ExpectedState << ObservedState);
1650
1651    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1652  }
1653
1654  void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
1655                                              StringRef TypeName) override {
1656    PartialDiagnosticAt Warning(Loc, S.PDiag(
1657      diag::warn_return_typestate_for_unconsumable_type) << TypeName);
1658
1659    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1660  }
1661
1662  void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
1663                                   StringRef ObservedState) override {
1664
1665    PartialDiagnosticAt Warning(Loc, S.PDiag(
1666      diag::warn_return_typestate_mismatch) << ExpectedState << ObservedState);
1667
1668    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1669  }
1670
1671  void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State,
1672                                   SourceLocation Loc) override {
1673
1674    PartialDiagnosticAt Warning(Loc, S.PDiag(
1675      diag::warn_use_of_temp_in_invalid_state) << MethodName << State);
1676
1677    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1678  }
1679
1680  void warnUseInInvalidState(StringRef MethodName, StringRef VariableName,
1681                             StringRef State, SourceLocation Loc) override {
1682
1683    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state) <<
1684                                MethodName << VariableName << State);
1685
1686    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
1687  }
1688};
1689}}}
1690
1691//===----------------------------------------------------------------------===//
1692// AnalysisBasedWarnings - Worker object used by Sema to execute analysis-based
1693//  warnings on a function, method, or block.
1694//===----------------------------------------------------------------------===//
1695
1696clang::sema::AnalysisBasedWarnings::Policy::Policy() {
1697  enableCheckFallThrough = 1;
1698  enableCheckUnreachable = 0;
1699  enableThreadSafetyAnalysis = 0;
1700  enableConsumedAnalysis = 0;
1701}
1702
1703static unsigned isEnabled(DiagnosticsEngine &D, unsigned diag) {
1704  return (unsigned) D.getDiagnosticLevel(diag, SourceLocation()) !=
1705                    DiagnosticsEngine::Ignored;
1706}
1707
1708clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
1709  : S(s),
1710    NumFunctionsAnalyzed(0),
1711    NumFunctionsWithBadCFGs(0),
1712    NumCFGBlocks(0),
1713    MaxCFGBlocksPerFunction(0),
1714    NumUninitAnalysisFunctions(0),
1715    NumUninitAnalysisVariables(0),
1716    MaxUninitAnalysisVariablesPerFunction(0),
1717    NumUninitAnalysisBlockVisits(0),
1718    MaxUninitAnalysisBlockVisitsPerFunction(0) {
1719
1720  using namespace diag;
1721  DiagnosticsEngine &D = S.getDiagnostics();
1722
1723  DefaultPolicy.enableCheckUnreachable =
1724    isEnabled(D, warn_unreachable) ||
1725    isEnabled(D, warn_unreachable_break) ||
1726    isEnabled(D, warn_unreachable_return) ||
1727    isEnabled(D, warn_unreachable_loop_increment);
1728
1729  DefaultPolicy.enableThreadSafetyAnalysis =
1730    isEnabled(D, warn_double_lock);
1731
1732  DefaultPolicy.enableConsumedAnalysis =
1733    isEnabled(D, warn_use_in_invalid_state);
1734}
1735
1736static void flushDiagnostics(Sema &S, sema::FunctionScopeInfo *fscope) {
1737  for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
1738       i = fscope->PossiblyUnreachableDiags.begin(),
1739       e = fscope->PossiblyUnreachableDiags.end();
1740       i != e; ++i) {
1741    const sema::PossiblyUnreachableDiag &D = *i;
1742    S.Diag(D.Loc, D.PD);
1743  }
1744}
1745
1746void clang::sema::
1747AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
1748                                     sema::FunctionScopeInfo *fscope,
1749                                     const Decl *D, const BlockExpr *blkExpr) {
1750
1751  // We avoid doing analysis-based warnings when there are errors for
1752  // two reasons:
1753  // (1) The CFGs often can't be constructed (if the body is invalid), so
1754  //     don't bother trying.
1755  // (2) The code already has problems; running the analysis just takes more
1756  //     time.
1757  DiagnosticsEngine &Diags = S.getDiagnostics();
1758
1759  // Do not do any analysis for declarations in system headers if we are
1760  // going to just ignore them.
1761  if (Diags.getSuppressSystemWarnings() &&
1762      S.SourceMgr.isInSystemHeader(D->getLocation()))
1763    return;
1764
1765  // For code in dependent contexts, we'll do this at instantiation time.
1766  if (cast<DeclContext>(D)->isDependentContext())
1767    return;
1768
1769  if (Diags.hasUncompilableErrorOccurred() || Diags.hasFatalErrorOccurred()) {
1770    // Flush out any possibly unreachable diagnostics.
1771    flushDiagnostics(S, fscope);
1772    return;
1773  }
1774
1775  const Stmt *Body = D->getBody();
1776  assert(Body);
1777
1778  // Construct the analysis context with the specified CFG build options.
1779  AnalysisDeclContext AC(/* AnalysisDeclContextManager */ 0, D);
1780
1781  // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
1782  // explosion for destructors that can result and the compile time hit.
1783  AC.getCFGBuildOptions().PruneTriviallyFalseEdges = true;
1784  AC.getCFGBuildOptions().AddEHEdges = false;
1785  AC.getCFGBuildOptions().AddInitializers = true;
1786  AC.getCFGBuildOptions().AddImplicitDtors = true;
1787  AC.getCFGBuildOptions().AddTemporaryDtors = true;
1788  AC.getCFGBuildOptions().AddCXXNewAllocator = false;
1789
1790  // Force that certain expressions appear as CFGElements in the CFG.  This
1791  // is used to speed up various analyses.
1792  // FIXME: This isn't the right factoring.  This is here for initial
1793  // prototyping, but we need a way for analyses to say what expressions they
1794  // expect to always be CFGElements and then fill in the BuildOptions
1795  // appropriately.  This is essentially a layering violation.
1796  if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis ||
1797      P.enableConsumedAnalysis) {
1798    // Unreachable code analysis and thread safety require a linearized CFG.
1799    AC.getCFGBuildOptions().setAllAlwaysAdd();
1800  }
1801  else {
1802    AC.getCFGBuildOptions()
1803      .setAlwaysAdd(Stmt::BinaryOperatorClass)
1804      .setAlwaysAdd(Stmt::CompoundAssignOperatorClass)
1805      .setAlwaysAdd(Stmt::BlockExprClass)
1806      .setAlwaysAdd(Stmt::CStyleCastExprClass)
1807      .setAlwaysAdd(Stmt::DeclRefExprClass)
1808      .setAlwaysAdd(Stmt::ImplicitCastExprClass)
1809      .setAlwaysAdd(Stmt::UnaryOperatorClass)
1810      .setAlwaysAdd(Stmt::AttributedStmtClass);
1811  }
1812
1813
1814  // Emit delayed diagnostics.
1815  if (!fscope->PossiblyUnreachableDiags.empty()) {
1816    bool analyzed = false;
1817
1818    // Register the expressions with the CFGBuilder.
1819    for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
1820         i = fscope->PossiblyUnreachableDiags.begin(),
1821         e = fscope->PossiblyUnreachableDiags.end();
1822         i != e; ++i) {
1823      if (const Stmt *stmt = i->stmt)
1824        AC.registerForcedBlockExpression(stmt);
1825    }
1826
1827    if (AC.getCFG()) {
1828      analyzed = true;
1829      for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
1830            i = fscope->PossiblyUnreachableDiags.begin(),
1831            e = fscope->PossiblyUnreachableDiags.end();
1832            i != e; ++i)
1833      {
1834        const sema::PossiblyUnreachableDiag &D = *i;
1835        bool processed = false;
1836        if (const Stmt *stmt = i->stmt) {
1837          const CFGBlock *block = AC.getBlockForRegisteredExpression(stmt);
1838          CFGReverseBlockReachabilityAnalysis *cra =
1839              AC.getCFGReachablityAnalysis();
1840          // FIXME: We should be able to assert that block is non-null, but
1841          // the CFG analysis can skip potentially-evaluated expressions in
1842          // edge cases; see test/Sema/vla-2.c.
1843          if (block && cra) {
1844            // Can this block be reached from the entrance?
1845            if (cra->isReachable(&AC.getCFG()->getEntry(), block))
1846              S.Diag(D.Loc, D.PD);
1847            processed = true;
1848          }
1849        }
1850        if (!processed) {
1851          // Emit the warning anyway if we cannot map to a basic block.
1852          S.Diag(D.Loc, D.PD);
1853        }
1854      }
1855    }
1856
1857    if (!analyzed)
1858      flushDiagnostics(S, fscope);
1859  }
1860
1861
1862  // Warning: check missing 'return'
1863  if (P.enableCheckFallThrough) {
1864    const CheckFallThroughDiagnostics &CD =
1865      (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
1866       : (isa<CXXMethodDecl>(D) &&
1867          cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call &&
1868          cast<CXXMethodDecl>(D)->getParent()->isLambda())
1869            ? CheckFallThroughDiagnostics::MakeForLambda()
1870            : CheckFallThroughDiagnostics::MakeForFunction(D));
1871    CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC);
1872  }
1873
1874  // Warning: check for unreachable code
1875  if (P.enableCheckUnreachable) {
1876    // Only check for unreachable code on non-template instantiations.
1877    // Different template instantiations can effectively change the control-flow
1878    // and it is very difficult to prove that a snippet of code in a template
1879    // is unreachable for all instantiations.
1880    bool isTemplateInstantiation = false;
1881    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
1882      isTemplateInstantiation = Function->isTemplateInstantiation();
1883    if (!isTemplateInstantiation)
1884      CheckUnreachable(S, AC);
1885  }
1886
1887  // Check for thread safety violations
1888  if (P.enableThreadSafetyAnalysis) {
1889    SourceLocation FL = AC.getDecl()->getLocation();
1890    SourceLocation FEL = AC.getDecl()->getLocEnd();
1891    thread_safety::ThreadSafetyReporter Reporter(S, FL, FEL);
1892    if (Diags.getDiagnosticLevel(diag::warn_thread_safety_beta,D->getLocStart())
1893        != DiagnosticsEngine::Ignored)
1894      Reporter.setIssueBetaWarnings(true);
1895
1896    thread_safety::runThreadSafetyAnalysis(AC, Reporter);
1897    Reporter.emitDiagnostics();
1898  }
1899
1900  // Check for violations of consumed properties.
1901  if (P.enableConsumedAnalysis) {
1902    consumed::ConsumedWarningsHandler WarningHandler(S);
1903    consumed::ConsumedAnalyzer Analyzer(WarningHandler);
1904    Analyzer.run(AC);
1905  }
1906
1907  if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart())
1908      != DiagnosticsEngine::Ignored ||
1909      Diags.getDiagnosticLevel(diag::warn_sometimes_uninit_var,D->getLocStart())
1910      != DiagnosticsEngine::Ignored ||
1911      Diags.getDiagnosticLevel(diag::warn_maybe_uninit_var, D->getLocStart())
1912      != DiagnosticsEngine::Ignored) {
1913    if (CFG *cfg = AC.getCFG()) {
1914      UninitValsDiagReporter reporter(S);
1915      UninitVariablesAnalysisStats stats;
1916      std::memset(&stats, 0, sizeof(UninitVariablesAnalysisStats));
1917      runUninitializedVariablesAnalysis(*cast<DeclContext>(D), *cfg, AC,
1918                                        reporter, stats);
1919
1920      if (S.CollectStats && stats.NumVariablesAnalyzed > 0) {
1921        ++NumUninitAnalysisFunctions;
1922        NumUninitAnalysisVariables += stats.NumVariablesAnalyzed;
1923        NumUninitAnalysisBlockVisits += stats.NumBlockVisits;
1924        MaxUninitAnalysisVariablesPerFunction =
1925            std::max(MaxUninitAnalysisVariablesPerFunction,
1926                     stats.NumVariablesAnalyzed);
1927        MaxUninitAnalysisBlockVisitsPerFunction =
1928            std::max(MaxUninitAnalysisBlockVisitsPerFunction,
1929                     stats.NumBlockVisits);
1930      }
1931    }
1932  }
1933
1934  bool FallThroughDiagFull =
1935      Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough,
1936                               D->getLocStart()) != DiagnosticsEngine::Ignored;
1937  bool FallThroughDiagPerFunction =
1938      Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough_per_function,
1939                               D->getLocStart()) != DiagnosticsEngine::Ignored;
1940  if (FallThroughDiagFull || FallThroughDiagPerFunction) {
1941    DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull);
1942  }
1943
1944  if (S.getLangOpts().ObjCARCWeak &&
1945      Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
1946                               D->getLocStart()) != DiagnosticsEngine::Ignored)
1947    diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap());
1948
1949
1950  // Check for infinite self-recursion in functions
1951  if (Diags.getDiagnosticLevel(diag::warn_infinite_recursive_function,
1952                               D->getLocStart())
1953      != DiagnosticsEngine::Ignored) {
1954    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1955      checkRecursiveFunction(S, FD, Body, AC);
1956    }
1957  }
1958
1959  // Collect statistics about the CFG if it was built.
1960  if (S.CollectStats && AC.isCFGBuilt()) {
1961    ++NumFunctionsAnalyzed;
1962    if (CFG *cfg = AC.getCFG()) {
1963      // If we successfully built a CFG for this context, record some more
1964      // detail information about it.
1965      NumCFGBlocks += cfg->getNumBlockIDs();
1966      MaxCFGBlocksPerFunction = std::max(MaxCFGBlocksPerFunction,
1967                                         cfg->getNumBlockIDs());
1968    } else {
1969      ++NumFunctionsWithBadCFGs;
1970    }
1971  }
1972}
1973
1974void clang::sema::AnalysisBasedWarnings::PrintStats() const {
1975  llvm::errs() << "\n*** Analysis Based Warnings Stats:\n";
1976
1977  unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs;
1978  unsigned AvgCFGBlocksPerFunction =
1979      !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt;
1980  llvm::errs() << NumFunctionsAnalyzed << " functions analyzed ("
1981               << NumFunctionsWithBadCFGs << " w/o CFGs).\n"
1982               << "  " << NumCFGBlocks << " CFG blocks built.\n"
1983               << "  " << AvgCFGBlocksPerFunction
1984               << " average CFG blocks per function.\n"
1985               << "  " << MaxCFGBlocksPerFunction
1986               << " max CFG blocks per function.\n";
1987
1988  unsigned AvgUninitVariablesPerFunction = !NumUninitAnalysisFunctions ? 0
1989      : NumUninitAnalysisVariables/NumUninitAnalysisFunctions;
1990  unsigned AvgUninitBlockVisitsPerFunction = !NumUninitAnalysisFunctions ? 0
1991      : NumUninitAnalysisBlockVisits/NumUninitAnalysisFunctions;
1992  llvm::errs() << NumUninitAnalysisFunctions
1993               << " functions analyzed for uninitialiazed variables\n"
1994               << "  " << NumUninitAnalysisVariables << " variables analyzed.\n"
1995               << "  " << AvgUninitVariablesPerFunction
1996               << " average variables per function.\n"
1997               << "  " << MaxUninitAnalysisVariablesPerFunction
1998               << " max variables per function.\n"
1999               << "  " << NumUninitAnalysisBlockVisits << " block visits.\n"
2000               << "  " << AvgUninitBlockVisitsPerFunction
2001               << " average block visits per function.\n"
2002               << "  " << MaxUninitAnalysisBlockVisitsPerFunction
2003               << " max block visits per function.\n";
2004}
2005