//===- Consumed.cpp --------------------------------------------*- C++ --*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// A intra-procedural analysis for checking consumed properties.  This is based,
// in part, on research on linear types.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/Analyses/Consumed.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Analysis/CFG.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include <memory>

// TODO: Adjust states of args to constructors in the same way that arguments to
//       function calls are handled.
// TODO: Use information from tests in for- and while-loop conditional.
// TODO: Add notes about the actual and expected state for 
// TODO: Correctly identify unreachable blocks when chaining boolean operators.
// TODO: Adjust the parser and AttributesList class to support lists of
//       identifiers.
// TODO: Warn about unreachable code.
// TODO: Switch to using a bitmap to track unreachable blocks.
// TODO: Handle variable definitions, e.g. bool valid = x.isValid();
//       if (valid) ...; (Deferred)
// TODO: Take notes on state transitions to provide better warning messages.
//       (Deferred)
// TODO: Test nested conditionals: A) Checking the same value multiple times,
//       and 2) Checking different values. (Deferred)

using namespace clang;
using namespace consumed;

// Key method definition
ConsumedWarningsHandlerBase::~ConsumedWarningsHandlerBase() {}

static SourceLocation getFirstStmtLoc(const CFGBlock *Block) {
  // Find the source location of the first statement in the block, if the block
  // is not empty.
  for (const auto &B : *Block)
    if (Optional<CFGStmt> CS = B.getAs<CFGStmt>())
      return CS->getStmt()->getLocStart();

  // Block is empty.
  // If we have one successor, return the first statement in that block
  if (Block->succ_size() == 1 && *Block->succ_begin())
    return getFirstStmtLoc(*Block->succ_begin());

  return SourceLocation();
}

static SourceLocation getLastStmtLoc(const CFGBlock *Block) {
  // Find the source location of the last statement in the block, if the block
  // is not empty.
  if (const Stmt *StmtNode = Block->getTerminator()) {
    return StmtNode->getLocStart();
  } else {
    for (CFGBlock::const_reverse_iterator BI = Block->rbegin(),
         BE = Block->rend(); BI != BE; ++BI) {
      if (Optional<CFGStmt> CS = BI->getAs<CFGStmt>())
        return CS->getStmt()->getLocStart();
    }
  }

  // If we have one successor, return the first statement in that block
  SourceLocation Loc;
  if (Block->succ_size() == 1 && *Block->succ_begin())
    Loc = getFirstStmtLoc(*Block->succ_begin());
  if (Loc.isValid())
    return Loc;

  // If we have one predecessor, return the last statement in that block
  if (Block->pred_size() == 1 && *Block->pred_begin())
    return getLastStmtLoc(*Block->pred_begin());

  return Loc;
}

static ConsumedState invertConsumedUnconsumed(ConsumedState State) {
  switch (State) {
  case CS_Unconsumed:
    return CS_Consumed;
  case CS_Consumed:
    return CS_Unconsumed;
  case CS_None:
    return CS_None;
  case CS_Unknown:
    return CS_Unknown;
  }
  llvm_unreachable("invalid enum");
}

static bool isCallableInState(const CallableWhenAttr *CWAttr,
                              ConsumedState State) {
  
  for (const auto &S : CWAttr->callableStates()) {
    ConsumedState MappedAttrState = CS_None;

    switch (S) {
    case CallableWhenAttr::Unknown:
      MappedAttrState = CS_Unknown;
      break;
      
    case CallableWhenAttr::Unconsumed:
      MappedAttrState = CS_Unconsumed;
      break;
      
    case CallableWhenAttr::Consumed:
      MappedAttrState = CS_Consumed;
      break;
    }
    
    if (MappedAttrState == State)
      return true;
  }
  
  return false;
}


static bool isConsumableType(const QualType &QT) {
  if (QT->isPointerType() || QT->isReferenceType())
    return false;
  
  if (const CXXRecordDecl *RD = QT->getAsCXXRecordDecl())
    return RD->hasAttr<ConsumableAttr>();
  
  return false;
}

static bool isAutoCastType(const QualType &QT) {
  if (QT->isPointerType() || QT->isReferenceType())
    return false;

  if (const CXXRecordDecl *RD = QT->getAsCXXRecordDecl())
    return RD->hasAttr<ConsumableAutoCastAttr>();

  return false;
}

static bool isSetOnReadPtrType(const QualType &QT) {
  if (const CXXRecordDecl *RD = QT->getPointeeCXXRecordDecl())
    return RD->hasAttr<ConsumableSetOnReadAttr>();
  return false;
}


static bool isKnownState(ConsumedState State) {
  switch (State) {
  case CS_Unconsumed:
  case CS_Consumed:
    return true;
  case CS_None:
  case CS_Unknown:
    return false;
  }
  llvm_unreachable("invalid enum");
}

static bool isRValueRef(QualType ParamType) {
  return ParamType->isRValueReferenceType();
}

static bool isTestingFunction(const FunctionDecl *FunDecl) {
  return FunDecl->hasAttr<TestTypestateAttr>();
}

static bool isPointerOrRef(QualType ParamType) {
  return ParamType->isPointerType() || ParamType->isReferenceType();
}

static ConsumedState mapConsumableAttrState(const QualType QT) {
  assert(isConsumableType(QT));

  const ConsumableAttr *CAttr =
      QT->getAsCXXRecordDecl()->getAttr<ConsumableAttr>();

  switch (CAttr->getDefaultState()) {
  case ConsumableAttr::Unknown:
    return CS_Unknown;
  case ConsumableAttr::Unconsumed:
    return CS_Unconsumed;
  case ConsumableAttr::Consumed:
    return CS_Consumed;
  }
  llvm_unreachable("invalid enum");
}

static ConsumedState
mapParamTypestateAttrState(const ParamTypestateAttr *PTAttr) {
  switch (PTAttr->getParamState()) {
  case ParamTypestateAttr::Unknown:
    return CS_Unknown;
  case ParamTypestateAttr::Unconsumed:
    return CS_Unconsumed;
  case ParamTypestateAttr::Consumed:
    return CS_Consumed;
  }
  llvm_unreachable("invalid_enum");
}

static ConsumedState
mapReturnTypestateAttrState(const ReturnTypestateAttr *RTSAttr) {
  switch (RTSAttr->getState()) {
  case ReturnTypestateAttr::Unknown:
    return CS_Unknown;
  case ReturnTypestateAttr::Unconsumed:
    return CS_Unconsumed;
  case ReturnTypestateAttr::Consumed:
    return CS_Consumed;
  }
  llvm_unreachable("invalid enum");
}

static ConsumedState mapSetTypestateAttrState(const SetTypestateAttr *STAttr) {
  switch (STAttr->getNewState()) {
  case SetTypestateAttr::Unknown:
    return CS_Unknown;
  case SetTypestateAttr::Unconsumed:
    return CS_Unconsumed;
  case SetTypestateAttr::Consumed:
    return CS_Consumed;
  }
  llvm_unreachable("invalid_enum");
}

static StringRef stateToString(ConsumedState State) {
  switch (State) {
  case consumed::CS_None:
    return "none";
  
  case consumed::CS_Unknown:
    return "unknown";
  
  case consumed::CS_Unconsumed:
    return "unconsumed";
  
  case consumed::CS_Consumed:
    return "consumed";
  }
  llvm_unreachable("invalid enum");
}

static ConsumedState testsFor(const FunctionDecl *FunDecl) {
  assert(isTestingFunction(FunDecl));
  switch (FunDecl->getAttr<TestTypestateAttr>()->getTestState()) {
  case TestTypestateAttr::Unconsumed:
    return CS_Unconsumed;
  case TestTypestateAttr::Consumed:
    return CS_Consumed;
  }
  llvm_unreachable("invalid enum");
}

namespace {
struct VarTestResult {
  const VarDecl *Var;
  ConsumedState TestsFor;
};
} // end anonymous::VarTestResult

namespace clang {
namespace consumed {

enum EffectiveOp {
  EO_And,
  EO_Or
};

class PropagationInfo {
  enum {
    IT_None,
    IT_State,
    IT_VarTest,
    IT_BinTest,
    IT_Var,
    IT_Tmp
  } InfoType;

  struct BinTestTy {
    const BinaryOperator *Source;
    EffectiveOp EOp;
    VarTestResult LTest;
    VarTestResult RTest;
  };
  
  union {
    ConsumedState State;
    VarTestResult VarTest;
    const VarDecl *Var;
    const CXXBindTemporaryExpr *Tmp;
    BinTestTy BinTest;
  };
  
public:
  PropagationInfo() : InfoType(IT_None) {}
  
  PropagationInfo(const VarTestResult &VarTest)
    : InfoType(IT_VarTest), VarTest(VarTest) {}
  
  PropagationInfo(const VarDecl *Var, ConsumedState TestsFor)
    : InfoType(IT_VarTest) {
    
    VarTest.Var      = Var;
    VarTest.TestsFor = TestsFor;
  }
  
  PropagationInfo(const BinaryOperator *Source, EffectiveOp EOp,
                  const VarTestResult &LTest, const VarTestResult &RTest)
    : InfoType(IT_BinTest) {
    
    BinTest.Source  = Source;
    BinTest.EOp     = EOp;
    BinTest.LTest   = LTest;
    BinTest.RTest   = RTest;
  }
  
  PropagationInfo(const BinaryOperator *Source, EffectiveOp EOp,
                  const VarDecl *LVar, ConsumedState LTestsFor,
                  const VarDecl *RVar, ConsumedState RTestsFor)
    : InfoType(IT_BinTest) {
    
    BinTest.Source         = Source;
    BinTest.EOp            = EOp;
    BinTest.LTest.Var      = LVar;
    BinTest.LTest.TestsFor = LTestsFor;
    BinTest.RTest.Var      = RVar;
    BinTest.RTest.TestsFor = RTestsFor;
  }
  
  PropagationInfo(ConsumedState State)
    : InfoType(IT_State), State(State) {}
  
  PropagationInfo(const VarDecl *Var) : InfoType(IT_Var), Var(Var) {}
  PropagationInfo(const CXXBindTemporaryExpr *Tmp)
    : InfoType(IT_Tmp), Tmp(Tmp) {}
  
  const ConsumedState & getState() const {
    assert(InfoType == IT_State);
    return State;
  }
  
  const VarTestResult & getVarTest() const {
    assert(InfoType == IT_VarTest);
    return VarTest;
  }
  
  const VarTestResult & getLTest() const {
    assert(InfoType == IT_BinTest);
    return BinTest.LTest;
  }
  
  const VarTestResult & getRTest() const {
    assert(InfoType == IT_BinTest);
    return BinTest.RTest;
  }
  
  const VarDecl * getVar() const {
    assert(InfoType == IT_Var);
    return Var;
  }
  
  const CXXBindTemporaryExpr * getTmp() const {
    assert(InfoType == IT_Tmp);
    return Tmp;
  }
  
  ConsumedState getAsState(const ConsumedStateMap *StateMap) const {
    assert(isVar() || isTmp() || isState());
    
    if (isVar())
      return StateMap->getState(Var);
    else if (isTmp())
      return StateMap->getState(Tmp);
    else if (isState())
      return State;
    else
      return CS_None;
  }
  
  EffectiveOp testEffectiveOp() const {
    assert(InfoType == IT_BinTest);
    return BinTest.EOp;
  }
  
  const BinaryOperator * testSourceNode() const {
    assert(InfoType == IT_BinTest);
    return BinTest.Source;
  }
  
  inline bool isValid()   const { return InfoType != IT_None;    }
  inline bool isState()   const { return InfoType == IT_State;   }
  inline bool isVarTest() const { return InfoType == IT_VarTest; }
  inline bool isBinTest() const { return InfoType == IT_BinTest; }
  inline bool isVar()     const { return InfoType == IT_Var;     }
  inline bool isTmp()     const { return InfoType == IT_Tmp;     }
  
  bool isTest() const {
    return InfoType == IT_VarTest || InfoType == IT_BinTest;
  }
  
  bool isPointerToValue() const {
    return InfoType == IT_Var || InfoType == IT_Tmp;
  }
  
  PropagationInfo invertTest() const {
    assert(InfoType == IT_VarTest || InfoType == IT_BinTest);
    
    if (InfoType == IT_VarTest) {
      return PropagationInfo(VarTest.Var,
                             invertConsumedUnconsumed(VarTest.TestsFor));
    
    } else if (InfoType == IT_BinTest) {
      return PropagationInfo(BinTest.Source,
        BinTest.EOp == EO_And ? EO_Or : EO_And,
        BinTest.LTest.Var, invertConsumedUnconsumed(BinTest.LTest.TestsFor),
        BinTest.RTest.Var, invertConsumedUnconsumed(BinTest.RTest.TestsFor));
    } else {
      return PropagationInfo();
    }
  }
};

static inline void
setStateForVarOrTmp(ConsumedStateMap *StateMap, const PropagationInfo &PInfo,
                    ConsumedState State) {

  assert(PInfo.isVar() || PInfo.isTmp());
  
  if (PInfo.isVar())
    StateMap->setState(PInfo.getVar(), State);
  else
    StateMap->setState(PInfo.getTmp(), State);
}

class ConsumedStmtVisitor : public ConstStmtVisitor<ConsumedStmtVisitor> {
  
  typedef llvm::DenseMap<const Stmt *, PropagationInfo> MapType;
  typedef std::pair<const Stmt *, PropagationInfo> PairType;
  typedef MapType::iterator InfoEntry;
  typedef MapType::const_iterator ConstInfoEntry;
  
  AnalysisDeclContext &AC;
  ConsumedAnalyzer &Analyzer;
  ConsumedStateMap *StateMap;
  MapType PropagationMap;

  InfoEntry findInfo(const Expr *E) {
    if (auto Cleanups = dyn_cast<ExprWithCleanups>(E))
      if (!Cleanups->cleanupsHaveSideEffects())
        E = Cleanups->getSubExpr();
    return PropagationMap.find(E->IgnoreParens());
  }
  ConstInfoEntry findInfo(const Expr *E) const {
    if (auto Cleanups = dyn_cast<ExprWithCleanups>(E))
      if (!Cleanups->cleanupsHaveSideEffects())
        E = Cleanups->getSubExpr();
    return PropagationMap.find(E->IgnoreParens());
  }
  void insertInfo(const Expr *E, const PropagationInfo &PI) {
    PropagationMap.insert(PairType(E->IgnoreParens(), PI));
  }

  void forwardInfo(const Expr *From, const Expr *To);
  void copyInfo(const Expr *From, const Expr *To, ConsumedState CS);
  ConsumedState getInfo(const Expr *From);
  void setInfo(const Expr *To, ConsumedState NS);
  void propagateReturnType(const Expr *Call, const FunctionDecl *Fun);

public:
  void checkCallability(const PropagationInfo &PInfo,
                        const FunctionDecl *FunDecl,
                        SourceLocation BlameLoc);
  bool handleCall(const CallExpr *Call, const Expr *ObjArg,
                  const FunctionDecl *FunD);
  
  void VisitBinaryOperator(const BinaryOperator *BinOp);
  void VisitCallExpr(const CallExpr *Call);
  void VisitCastExpr(const CastExpr *Cast);
  void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Temp);
  void VisitCXXConstructExpr(const CXXConstructExpr *Call);
  void VisitCXXMemberCallExpr(const CXXMemberCallExpr *Call);
  void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Call);
  void VisitDeclRefExpr(const DeclRefExpr *DeclRef);
  void VisitDeclStmt(const DeclStmt *DelcS);
  void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Temp);
  void VisitMemberExpr(const MemberExpr *MExpr);
  void VisitParmVarDecl(const ParmVarDecl *Param);
  void VisitReturnStmt(const ReturnStmt *Ret);
  void VisitUnaryOperator(const UnaryOperator *UOp);
  void VisitVarDecl(const VarDecl *Var);

  ConsumedStmtVisitor(AnalysisDeclContext &AC, ConsumedAnalyzer &Analyzer,
                      ConsumedStateMap *StateMap)
      : AC(AC), Analyzer(Analyzer), StateMap(StateMap) {}
  
  PropagationInfo getInfo(const Expr *StmtNode) const {
    ConstInfoEntry Entry = findInfo(StmtNode);
    
    if (Entry != PropagationMap.end())
      return Entry->second;
    else
      return PropagationInfo();
  }
  
  void reset(ConsumedStateMap *NewStateMap) {
    StateMap = NewStateMap;
  }
};


void ConsumedStmtVisitor::forwardInfo(const Expr *From, const Expr *To) {
  InfoEntry Entry = findInfo(From);
  if (Entry != PropagationMap.end())
    insertInfo(To, Entry->second);
}


// Create a new state for To, which is initialized to the state of From.
// If NS is not CS_None, sets the state of From to NS.
void ConsumedStmtVisitor::copyInfo(const Expr *From, const Expr *To,
                                   ConsumedState NS) {
  InfoEntry Entry = findInfo(From);
  if (Entry != PropagationMap.end()) {
    PropagationInfo& PInfo = Entry->second;
    ConsumedState CS = PInfo.getAsState(StateMap);
    if (CS != CS_None)
      insertInfo(To, PropagationInfo(CS));
    if (NS != CS_None && PInfo.isPointerToValue())
      setStateForVarOrTmp(StateMap, PInfo, NS);
  }
}


// Get the ConsumedState for From
ConsumedState ConsumedStmtVisitor::getInfo(const Expr *From) {
  InfoEntry Entry = findInfo(From);
  if (Entry != PropagationMap.end()) {
    PropagationInfo& PInfo = Entry->second;
    return PInfo.getAsState(StateMap);
  }
  return CS_None;
}


// If we already have info for To then update it, otherwise create a new entry.
void ConsumedStmtVisitor::setInfo(const Expr *To, ConsumedState NS) {
  InfoEntry Entry = findInfo(To);
  if (Entry != PropagationMap.end()) {
    PropagationInfo& PInfo = Entry->second;
    if (PInfo.isPointerToValue())
      setStateForVarOrTmp(StateMap, PInfo, NS);
  } else if (NS != CS_None) {
     insertInfo(To, PropagationInfo(NS));
  }
}



void ConsumedStmtVisitor::checkCallability(const PropagationInfo &PInfo,
                                           const FunctionDecl *FunDecl,
                                           SourceLocation BlameLoc) {
  assert(!PInfo.isTest());

  const CallableWhenAttr *CWAttr = FunDecl->getAttr<CallableWhenAttr>();
  if (!CWAttr)
    return;

  if (PInfo.isVar()) {
    ConsumedState VarState = StateMap->getState(PInfo.getVar());

    if (VarState == CS_None || isCallableInState(CWAttr, VarState))
      return;

    Analyzer.WarningsHandler.warnUseInInvalidState(
      FunDecl->getNameAsString(), PInfo.getVar()->getNameAsString(),
      stateToString(VarState), BlameLoc);

  } else {
    ConsumedState TmpState = PInfo.getAsState(StateMap);

    if (TmpState == CS_None || isCallableInState(CWAttr, TmpState))
      return;

    Analyzer.WarningsHandler.warnUseOfTempInInvalidState(
      FunDecl->getNameAsString(), stateToString(TmpState), BlameLoc);
  }
}


// Factors out common behavior for function, method, and operator calls.
// Check parameters and set parameter state if necessary.
// Returns true if the state of ObjArg is set, or false otherwise.
bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg,
                                     const FunctionDecl *FunD) {
  unsigned Offset = 0;
  if (isa<CXXOperatorCallExpr>(Call) && isa<CXXMethodDecl>(FunD))
    Offset = 1;  // first argument is 'this'

  // check explicit parameters
  for (unsigned Index = Offset; Index < Call->getNumArgs(); ++Index) {
    // Skip variable argument lists.
    if (Index - Offset >= FunD->getNumParams())
      break;

    const ParmVarDecl *Param = FunD->getParamDecl(Index - Offset);
    QualType ParamType = Param->getType();

    InfoEntry Entry = findInfo(Call->getArg(Index));

    if (Entry == PropagationMap.end() || Entry->second.isTest())
      continue;
    PropagationInfo PInfo = Entry->second;

    // Check that the parameter is in the correct state.
    if (ParamTypestateAttr *PTA = Param->getAttr<ParamTypestateAttr>()) {
      ConsumedState ParamState = PInfo.getAsState(StateMap);
      ConsumedState ExpectedState = mapParamTypestateAttrState(PTA);

      if (ParamState != ExpectedState)
        Analyzer.WarningsHandler.warnParamTypestateMismatch(
          Call->getArg(Index)->getExprLoc(),
          stateToString(ExpectedState), stateToString(ParamState));
    }

    if (!(Entry->second.isVar() || Entry->second.isTmp()))
      continue;

    // Adjust state on the caller side.
    if (isRValueRef(ParamType))
      setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Consumed);
    else if (ReturnTypestateAttr *RT = Param->getAttr<ReturnTypestateAttr>())
      setStateForVarOrTmp(StateMap, PInfo, mapReturnTypestateAttrState(RT));
    else if (isPointerOrRef(ParamType) &&
             (!ParamType->getPointeeType().isConstQualified() ||
              isSetOnReadPtrType(ParamType)))
      setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Unknown);
  }

  if (!ObjArg)
    return false;

  // check implicit 'self' parameter, if present
  InfoEntry Entry = findInfo(ObjArg);
  if (Entry != PropagationMap.end()) {
    PropagationInfo PInfo = Entry->second;
    checkCallability(PInfo, FunD, Call->getExprLoc());

    if (SetTypestateAttr *STA = FunD->getAttr<SetTypestateAttr>()) {
      if (PInfo.isVar()) {
        StateMap->setState(PInfo.getVar(), mapSetTypestateAttrState(STA));
        return true;
      }
      else if (PInfo.isTmp()) {
        StateMap->setState(PInfo.getTmp(), mapSetTypestateAttrState(STA));
        return true;
      }
    }
    else if (isTestingFunction(FunD) && PInfo.isVar()) {
      PropagationMap.insert(PairType(Call,
        PropagationInfo(PInfo.getVar(), testsFor(FunD))));
    }
  }
  return false;
}


void ConsumedStmtVisitor::propagateReturnType(const Expr *Call,
                                              const FunctionDecl *Fun) {
  QualType RetType = Fun->getCallResultType();
  if (RetType->isReferenceType())
    RetType = RetType->getPointeeType();

  if (isConsumableType(RetType)) {
    ConsumedState ReturnState;
    if (ReturnTypestateAttr *RTA = Fun->getAttr<ReturnTypestateAttr>())
      ReturnState = mapReturnTypestateAttrState(RTA);
    else
      ReturnState = mapConsumableAttrState(RetType);
    
    PropagationMap.insert(PairType(Call, PropagationInfo(ReturnState)));
  }
}


void ConsumedStmtVisitor::VisitBinaryOperator(const BinaryOperator *BinOp) {
  switch (BinOp->getOpcode()) {
  case BO_LAnd:
  case BO_LOr : {
    InfoEntry LEntry = findInfo(BinOp->getLHS()),
              REntry = findInfo(BinOp->getRHS());
    
    VarTestResult LTest, RTest;
    
    if (LEntry != PropagationMap.end() && LEntry->second.isVarTest()) {
      LTest = LEntry->second.getVarTest();
      
    } else {
      LTest.Var      = nullptr;
      LTest.TestsFor = CS_None;
    }
    
    if (REntry != PropagationMap.end() && REntry->second.isVarTest()) {
      RTest = REntry->second.getVarTest();
      
    } else {
      RTest.Var      = nullptr;
      RTest.TestsFor = CS_None;
    }

    if (!(LTest.Var == nullptr && RTest.Var == nullptr))
      PropagationMap.insert(PairType(BinOp, PropagationInfo(BinOp,
        static_cast<EffectiveOp>(BinOp->getOpcode() == BO_LOr), LTest, RTest)));
    
    break;
  }
    
  case BO_PtrMemD:
  case BO_PtrMemI:
    forwardInfo(BinOp->getLHS(), BinOp);
    break;
    
  default:
    break;
  }
}

void ConsumedStmtVisitor::VisitCallExpr(const CallExpr *Call) {
  const FunctionDecl *FunDecl = Call->getDirectCallee();
  if (!FunDecl)
    return;

  // Special case for the std::move function.
  // TODO: Make this more specific. (Deferred)
  if (Call->getNumArgs() == 1 && FunDecl->getNameAsString() == "move" &&
      FunDecl->isInStdNamespace()) {
    copyInfo(Call->getArg(0), Call, CS_Consumed);
    return;
  }

  handleCall(Call, nullptr, FunDecl);
  propagateReturnType(Call, FunDecl);
}

void ConsumedStmtVisitor::VisitCastExpr(const CastExpr *Cast) {
  forwardInfo(Cast->getSubExpr(), Cast);
}

void ConsumedStmtVisitor::VisitCXXBindTemporaryExpr(
  const CXXBindTemporaryExpr *Temp) {
  
  InfoEntry Entry = findInfo(Temp->getSubExpr());
  
  if (Entry != PropagationMap.end() && !Entry->second.isTest()) {
    StateMap->setState(Temp, Entry->second.getAsState(StateMap));
    PropagationMap.insert(PairType(Temp, PropagationInfo(Temp)));
  }
}

void ConsumedStmtVisitor::VisitCXXConstructExpr(const CXXConstructExpr *Call) {
  CXXConstructorDecl *Constructor = Call->getConstructor();

  ASTContext &CurrContext = AC.getASTContext();
  QualType ThisType = Constructor->getThisType(CurrContext)->getPointeeType();
  
  if (!isConsumableType(ThisType))
    return;
  
  // FIXME: What should happen if someone annotates the move constructor?
  if (ReturnTypestateAttr *RTA = Constructor->getAttr<ReturnTypestateAttr>()) {
    // TODO: Adjust state of args appropriately.    
    ConsumedState RetState = mapReturnTypestateAttrState(RTA);
    PropagationMap.insert(PairType(Call, PropagationInfo(RetState)));
  } else if (Constructor->isDefaultConstructor()) {
    PropagationMap.insert(PairType(Call,
      PropagationInfo(consumed::CS_Consumed)));
  } else if (Constructor->isMoveConstructor()) {
    copyInfo(Call->getArg(0), Call, CS_Consumed);
  } else if (Constructor->isCopyConstructor()) {
    // Copy state from arg.  If setStateOnRead then set arg to CS_Unknown.
    ConsumedState NS =
      isSetOnReadPtrType(Constructor->getThisType(CurrContext)) ?
      CS_Unknown : CS_None;
    copyInfo(Call->getArg(0), Call, NS);
  } else {
    // TODO: Adjust state of args appropriately.
    ConsumedState RetState = mapConsumableAttrState(ThisType);
    PropagationMap.insert(PairType(Call, PropagationInfo(RetState)));
  }
}


void ConsumedStmtVisitor::VisitCXXMemberCallExpr(
    const CXXMemberCallExpr *Call) {
  CXXMethodDecl* MD = Call->getMethodDecl();
  if (!MD)
    return;

  handleCall(Call, Call->getImplicitObjectArgument(), MD);
  propagateReturnType(Call, MD);
}


void ConsumedStmtVisitor::VisitCXXOperatorCallExpr(
    const CXXOperatorCallExpr *Call) {

  const FunctionDecl *FunDecl =
    dyn_cast_or_null<FunctionDecl>(Call->getDirectCallee());
  if (!FunDecl) return;

  if (Call->getOperator() == OO_Equal) {
    ConsumedState CS = getInfo(Call->getArg(1));
    if (!handleCall(Call, Call->getArg(0), FunDecl))
      setInfo(Call->getArg(0), CS);
    return;
  }

  if (const CXXMemberCallExpr *MCall = dyn_cast<CXXMemberCallExpr>(Call))
    handleCall(MCall, MCall->getImplicitObjectArgument(), FunDecl);
  else
    handleCall(Call, Call->getArg(0), FunDecl);

  propagateReturnType(Call, FunDecl);
}

void ConsumedStmtVisitor::VisitDeclRefExpr(const DeclRefExpr *DeclRef) {
  if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(DeclRef->getDecl()))
    if (StateMap->getState(Var) != consumed::CS_None)
      PropagationMap.insert(PairType(DeclRef, PropagationInfo(Var)));
}

void ConsumedStmtVisitor::VisitDeclStmt(const DeclStmt *DeclS) {
  for (const auto *DI : DeclS->decls())    
    if (isa<VarDecl>(DI))
      VisitVarDecl(cast<VarDecl>(DI));
  
  if (DeclS->isSingleDecl())
    if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(DeclS->getSingleDecl()))
      PropagationMap.insert(PairType(DeclS, PropagationInfo(Var)));
}

void ConsumedStmtVisitor::VisitMaterializeTemporaryExpr(
  const MaterializeTemporaryExpr *Temp) {
  
  forwardInfo(Temp->GetTemporaryExpr(), Temp);
}

void ConsumedStmtVisitor::VisitMemberExpr(const MemberExpr *MExpr) {
  forwardInfo(MExpr->getBase(), MExpr);
}


void ConsumedStmtVisitor::VisitParmVarDecl(const ParmVarDecl *Param) {
  QualType ParamType = Param->getType();
  ConsumedState ParamState = consumed::CS_None;
  
  if (const ParamTypestateAttr *PTA = Param->getAttr<ParamTypestateAttr>())
    ParamState = mapParamTypestateAttrState(PTA);    
  else if (isConsumableType(ParamType))
    ParamState = mapConsumableAttrState(ParamType);    
  else if (isRValueRef(ParamType) &&
           isConsumableType(ParamType->getPointeeType()))
    ParamState = mapConsumableAttrState(ParamType->getPointeeType());    
  else if (ParamType->isReferenceType() &&
           isConsumableType(ParamType->getPointeeType()))
    ParamState = consumed::CS_Unknown;
  
  if (ParamState != CS_None)
    StateMap->setState(Param, ParamState);
}

void ConsumedStmtVisitor::VisitReturnStmt(const ReturnStmt *Ret) {
  ConsumedState ExpectedState = Analyzer.getExpectedReturnState();
  
  if (ExpectedState != CS_None) {
    InfoEntry Entry = findInfo(Ret->getRetValue());
    
    if (Entry != PropagationMap.end()) {
      ConsumedState RetState = Entry->second.getAsState(StateMap);
        
      if (RetState != ExpectedState)
        Analyzer.WarningsHandler.warnReturnTypestateMismatch(
          Ret->getReturnLoc(), stateToString(ExpectedState),
          stateToString(RetState));
    }
  }
  
  StateMap->checkParamsForReturnTypestate(Ret->getLocStart(),
                                          Analyzer.WarningsHandler);
}

void ConsumedStmtVisitor::VisitUnaryOperator(const UnaryOperator *UOp) {
  InfoEntry Entry = findInfo(UOp->getSubExpr());
  if (Entry == PropagationMap.end()) return;
  
  switch (UOp->getOpcode()) {
  case UO_AddrOf:
    PropagationMap.insert(PairType(UOp, Entry->second));
    break;
  
  case UO_LNot:
    if (Entry->second.isTest())
      PropagationMap.insert(PairType(UOp, Entry->second.invertTest()));
    break;
  
  default:
    break;
  }
}

// TODO: See if I need to check for reference types here.
void ConsumedStmtVisitor::VisitVarDecl(const VarDecl *Var) {
  if (isConsumableType(Var->getType())) {
    if (Var->hasInit()) {
      MapType::iterator VIT = findInfo(Var->getInit()->IgnoreImplicit());
      if (VIT != PropagationMap.end()) {
        PropagationInfo PInfo = VIT->second;
        ConsumedState St = PInfo.getAsState(StateMap);
        
        if (St != consumed::CS_None) {
          StateMap->setState(Var, St);
          return;
        }
      }
    }
    // Otherwise
    StateMap->setState(Var, consumed::CS_Unknown);
  }
}
}} // end clang::consumed::ConsumedStmtVisitor

namespace clang {
namespace consumed {

static void splitVarStateForIf(const IfStmt *IfNode, const VarTestResult &Test,
                               ConsumedStateMap *ThenStates,
                               ConsumedStateMap *ElseStates) {
  ConsumedState VarState = ThenStates->getState(Test.Var);
  
  if (VarState == CS_Unknown) {
    ThenStates->setState(Test.Var, Test.TestsFor);
    ElseStates->setState(Test.Var, invertConsumedUnconsumed(Test.TestsFor));
  
  } else if (VarState == invertConsumedUnconsumed(Test.TestsFor)) {
    ThenStates->markUnreachable();
    
  } else if (VarState == Test.TestsFor) {
    ElseStates->markUnreachable();
  }
}

static void splitVarStateForIfBinOp(const PropagationInfo &PInfo,
                                    ConsumedStateMap *ThenStates,
                                    ConsumedStateMap *ElseStates) {
  const VarTestResult &LTest = PInfo.getLTest(),
                      &RTest = PInfo.getRTest();
  
  ConsumedState LState = LTest.Var ? ThenStates->getState(LTest.Var) : CS_None,
                RState = RTest.Var ? ThenStates->getState(RTest.Var) : CS_None;
  
  if (LTest.Var) {
    if (PInfo.testEffectiveOp() == EO_And) {
      if (LState == CS_Unknown) {
        ThenStates->setState(LTest.Var, LTest.TestsFor);
        
      } else if (LState == invertConsumedUnconsumed(LTest.TestsFor)) {
        ThenStates->markUnreachable();
        
      } else if (LState == LTest.TestsFor && isKnownState(RState)) {
        if (RState == RTest.TestsFor)
          ElseStates->markUnreachable();
        else
          ThenStates->markUnreachable();
      }
      
    } else {
      if (LState == CS_Unknown) {
        ElseStates->setState(LTest.Var,
                             invertConsumedUnconsumed(LTest.TestsFor));
      
      } else if (LState == LTest.TestsFor) {
        ElseStates->markUnreachable();
        
      } else if (LState == invertConsumedUnconsumed(LTest.TestsFor) &&
                 isKnownState(RState)) {
        
        if (RState == RTest.TestsFor)
          ElseStates->markUnreachable();
        else
          ThenStates->markUnreachable();
      }
    }
  }
  
  if (RTest.Var) {
    if (PInfo.testEffectiveOp() == EO_And) {
      if (RState == CS_Unknown)
        ThenStates->setState(RTest.Var, RTest.TestsFor);
      else if (RState == invertConsumedUnconsumed(RTest.TestsFor))
        ThenStates->markUnreachable();
      
    } else {
      if (RState == CS_Unknown)
        ElseStates->setState(RTest.Var,
                             invertConsumedUnconsumed(RTest.TestsFor));
      else if (RState == RTest.TestsFor)
        ElseStates->markUnreachable();
    }
  }
}

bool ConsumedBlockInfo::allBackEdgesVisited(const CFGBlock *CurrBlock,
                                            const CFGBlock *TargetBlock) {
  
  assert(CurrBlock && "Block pointer must not be NULL");
  assert(TargetBlock && "TargetBlock pointer must not be NULL");
  
  unsigned int CurrBlockOrder = VisitOrder[CurrBlock->getBlockID()];
  for (CFGBlock::const_pred_iterator PI = TargetBlock->pred_begin(),
       PE = TargetBlock->pred_end(); PI != PE; ++PI) {
    if (*PI && CurrBlockOrder < VisitOrder[(*PI)->getBlockID()] )
      return false;
  }
  return true;
}

void ConsumedBlockInfo::addInfo(
    const CFGBlock *Block, ConsumedStateMap *StateMap,
    std::unique_ptr<ConsumedStateMap> &OwnedStateMap) {

  assert(Block && "Block pointer must not be NULL");

  auto &Entry = StateMapsArray[Block->getBlockID()];

  if (Entry) {
    Entry->intersect(*StateMap);
  } else if (OwnedStateMap)
    Entry = std::move(OwnedStateMap);
  else
    Entry = llvm::make_unique<ConsumedStateMap>(*StateMap);
}

void ConsumedBlockInfo::addInfo(const CFGBlock *Block,
                                std::unique_ptr<ConsumedStateMap> StateMap) {

  assert(Block && "Block pointer must not be NULL");

  auto &Entry = StateMapsArray[Block->getBlockID()];

  if (Entry) {
    Entry->intersect(*StateMap);
  } else {
    Entry = std::move(StateMap);
  }
}

ConsumedStateMap* ConsumedBlockInfo::borrowInfo(const CFGBlock *Block) {
  assert(Block && "Block pointer must not be NULL");
  assert(StateMapsArray[Block->getBlockID()] && "Block has no block info");

  return StateMapsArray[Block->getBlockID()].get();
}

void ConsumedBlockInfo::discardInfo(const CFGBlock *Block) {
  StateMapsArray[Block->getBlockID()] = nullptr;
}

std::unique_ptr<ConsumedStateMap>
ConsumedBlockInfo::getInfo(const CFGBlock *Block) {
  assert(Block && "Block pointer must not be NULL");

  auto &Entry = StateMapsArray[Block->getBlockID()];
  return isBackEdgeTarget(Block) ? llvm::make_unique<ConsumedStateMap>(*Entry)
                                 : std::move(Entry);
}

bool ConsumedBlockInfo::isBackEdge(const CFGBlock *From, const CFGBlock *To) {
  assert(From && "From block must not be NULL");
  assert(To   && "From block must not be NULL");
  
  return VisitOrder[From->getBlockID()] > VisitOrder[To->getBlockID()];
}

bool ConsumedBlockInfo::isBackEdgeTarget(const CFGBlock *Block) {
  assert(Block && "Block pointer must not be NULL");

  // Anything with less than two predecessors can't be the target of a back
  // edge.
  if (Block->pred_size() < 2)
    return false;
  
  unsigned int BlockVisitOrder = VisitOrder[Block->getBlockID()];
  for (CFGBlock::const_pred_iterator PI = Block->pred_begin(),
       PE = Block->pred_end(); PI != PE; ++PI) {
    if (*PI && BlockVisitOrder < VisitOrder[(*PI)->getBlockID()])
      return true;
  }
  return false;
}

void ConsumedStateMap::checkParamsForReturnTypestate(SourceLocation BlameLoc,
  ConsumedWarningsHandlerBase &WarningsHandler) const {
  
  for (const auto &DM : VarMap) {
    if (isa<ParmVarDecl>(DM.first)) {
      const ParmVarDecl *Param = cast<ParmVarDecl>(DM.first);
      const ReturnTypestateAttr *RTA = Param->getAttr<ReturnTypestateAttr>();
      
      if (!RTA)
        continue;
      
      ConsumedState ExpectedState = mapReturnTypestateAttrState(RTA);      
      if (DM.second != ExpectedState)
        WarningsHandler.warnParamReturnTypestateMismatch(BlameLoc,
          Param->getNameAsString(), stateToString(ExpectedState),
          stateToString(DM.second));
    }
  }
}

void ConsumedStateMap::clearTemporaries() {
  TmpMap.clear();
}

ConsumedState ConsumedStateMap::getState(const VarDecl *Var) const {
  VarMapType::const_iterator Entry = VarMap.find(Var);
  
  if (Entry != VarMap.end())
    return Entry->second;
    
  return CS_None;
}

ConsumedState
ConsumedStateMap::getState(const CXXBindTemporaryExpr *Tmp) const {
  TmpMapType::const_iterator Entry = TmpMap.find(Tmp);
  
  if (Entry != TmpMap.end())
    return Entry->second;
  
  return CS_None;
}

void ConsumedStateMap::intersect(const ConsumedStateMap &Other) {
  ConsumedState LocalState;

  if (this->From && this->From == Other.From && !Other.Reachable) {
    this->markUnreachable();
    return;
  }

  for (const auto &DM : Other.VarMap) {
    LocalState = this->getState(DM.first);
    
    if (LocalState == CS_None)
      continue;
    
    if (LocalState != DM.second)
     VarMap[DM.first] = CS_Unknown;
  }
}

void ConsumedStateMap::intersectAtLoopHead(const CFGBlock *LoopHead,
  const CFGBlock *LoopBack, const ConsumedStateMap *LoopBackStates,
  ConsumedWarningsHandlerBase &WarningsHandler) {
  
  ConsumedState LocalState;
  SourceLocation BlameLoc = getLastStmtLoc(LoopBack);
  
  for (const auto &DM : LoopBackStates->VarMap) {    
    LocalState = this->getState(DM.first);
    
    if (LocalState == CS_None)
      continue;
    
    if (LocalState != DM.second) {
      VarMap[DM.first] = CS_Unknown;
      WarningsHandler.warnLoopStateMismatch(BlameLoc,
                                            DM.first->getNameAsString());
    }
  }
}

void ConsumedStateMap::markUnreachable() {
  this->Reachable = false;
  VarMap.clear();
  TmpMap.clear();
}

void ConsumedStateMap::setState(const VarDecl *Var, ConsumedState State) {
  VarMap[Var] = State;
}

void ConsumedStateMap::setState(const CXXBindTemporaryExpr *Tmp,
                                ConsumedState State) {
  TmpMap[Tmp] = State;
}

void ConsumedStateMap::remove(const CXXBindTemporaryExpr *Tmp) {
  TmpMap.erase(Tmp);
}

bool ConsumedStateMap::operator!=(const ConsumedStateMap *Other) const {
  for (const auto &DM : Other->VarMap)
    if (this->getState(DM.first) != DM.second)
      return true;  
  return false;
}

void ConsumedAnalyzer::determineExpectedReturnState(AnalysisDeclContext &AC,
                                                    const FunctionDecl *D) {
  QualType ReturnType;
  if (const CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
    ASTContext &CurrContext = AC.getASTContext();
    ReturnType = Constructor->getThisType(CurrContext)->getPointeeType();
  } else
    ReturnType = D->getCallResultType();

  if (const ReturnTypestateAttr *RTSAttr = D->getAttr<ReturnTypestateAttr>()) {
    const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
    if (!RD || !RD->hasAttr<ConsumableAttr>()) {
      // FIXME: This should be removed when template instantiation propagates
      //        attributes at template specialization definition, not
      //        declaration. When it is removed the test needs to be enabled
      //        in SemaDeclAttr.cpp.
      WarningsHandler.warnReturnTypestateForUnconsumableType(
          RTSAttr->getLocation(), ReturnType.getAsString());
      ExpectedReturnState = CS_None;
    } else
      ExpectedReturnState = mapReturnTypestateAttrState(RTSAttr);
  } else if (isConsumableType(ReturnType)) {
    if (isAutoCastType(ReturnType))   // We can auto-cast the state to the
      ExpectedReturnState = CS_None;  // expected state.
    else
      ExpectedReturnState = mapConsumableAttrState(ReturnType);
  }
  else
    ExpectedReturnState = CS_None;
}

bool ConsumedAnalyzer::splitState(const CFGBlock *CurrBlock,
                                  const ConsumedStmtVisitor &Visitor) {

  std::unique_ptr<ConsumedStateMap> FalseStates(
      new ConsumedStateMap(*CurrStates));
  PropagationInfo PInfo;
  
  if (const IfStmt *IfNode =
    dyn_cast_or_null<IfStmt>(CurrBlock->getTerminator().getStmt())) {
    
    const Expr *Cond = IfNode->getCond();
    
    PInfo = Visitor.getInfo(Cond);
    if (!PInfo.isValid() && isa<BinaryOperator>(Cond))
      PInfo = Visitor.getInfo(cast<BinaryOperator>(Cond)->getRHS());
    
    if (PInfo.isVarTest()) {
      CurrStates->setSource(Cond);
      FalseStates->setSource(Cond);
      splitVarStateForIf(IfNode, PInfo.getVarTest(), CurrStates.get(),
                         FalseStates.get());

    } else if (PInfo.isBinTest()) {
      CurrStates->setSource(PInfo.testSourceNode());
      FalseStates->setSource(PInfo.testSourceNode());
      splitVarStateForIfBinOp(PInfo, CurrStates.get(), FalseStates.get());

    } else {
      return false;
    }
    
  } else if (const BinaryOperator *BinOp =
    dyn_cast_or_null<BinaryOperator>(CurrBlock->getTerminator().getStmt())) {
    
    PInfo = Visitor.getInfo(BinOp->getLHS());
    if (!PInfo.isVarTest()) {
      if ((BinOp = dyn_cast_or_null<BinaryOperator>(BinOp->getLHS()))) {
        PInfo = Visitor.getInfo(BinOp->getRHS());
        
        if (!PInfo.isVarTest())
          return false;
        
      } else {
        return false;
      }
    }
    
    CurrStates->setSource(BinOp);
    FalseStates->setSource(BinOp);
    
    const VarTestResult &Test = PInfo.getVarTest();
    ConsumedState VarState = CurrStates->getState(Test.Var);
    
    if (BinOp->getOpcode() == BO_LAnd) {
      if (VarState == CS_Unknown)
        CurrStates->setState(Test.Var, Test.TestsFor);
      else if (VarState == invertConsumedUnconsumed(Test.TestsFor))
        CurrStates->markUnreachable();
      
    } else if (BinOp->getOpcode() == BO_LOr) {
      if (VarState == CS_Unknown)
        FalseStates->setState(Test.Var,
                              invertConsumedUnconsumed(Test.TestsFor));
      else if (VarState == Test.TestsFor)
        FalseStates->markUnreachable();
    }
    
  } else {
    return false;
  }
  
  CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin();
  
  if (*SI)
    BlockInfo.addInfo(*SI, std::move(CurrStates));
  else
    CurrStates = nullptr;

  if (*++SI)
    BlockInfo.addInfo(*SI, std::move(FalseStates));

  return true;
}

void ConsumedAnalyzer::run(AnalysisDeclContext &AC) {
  const FunctionDecl *D = dyn_cast_or_null<FunctionDecl>(AC.getDecl());
  if (!D)
    return;
  
  CFG *CFGraph = AC.getCFG();
  if (!CFGraph)
    return;

  determineExpectedReturnState(AC, D);

  PostOrderCFGView *SortedGraph = AC.getAnalysis<PostOrderCFGView>();
  // AC.getCFG()->viewCFG(LangOptions());
  
  BlockInfo = ConsumedBlockInfo(CFGraph->getNumBlockIDs(), SortedGraph);

  CurrStates = llvm::make_unique<ConsumedStateMap>();
  ConsumedStmtVisitor Visitor(AC, *this, CurrStates.get());

  // Add all trackable parameters to the state map.
  for (const auto *PI : D->parameters())
    Visitor.VisitParmVarDecl(PI);
  
  // Visit all of the function's basic blocks.
  for (const auto *CurrBlock : *SortedGraph) {
    if (!CurrStates)
      CurrStates = BlockInfo.getInfo(CurrBlock);
    
    if (!CurrStates) {
      continue;
      
    } else if (!CurrStates->isReachable()) {
      CurrStates = nullptr;
      continue;
    }

    Visitor.reset(CurrStates.get());

    // Visit all of the basic block's statements.
    for (const auto &B : *CurrBlock) {
      switch (B.getKind()) {
      case CFGElement::Statement:
        Visitor.Visit(B.castAs<CFGStmt>().getStmt());
        break;
        
      case CFGElement::TemporaryDtor: {
        const CFGTemporaryDtor &DTor = B.castAs<CFGTemporaryDtor>();
        const CXXBindTemporaryExpr *BTE = DTor.getBindTemporaryExpr();
        
        Visitor.checkCallability(PropagationInfo(BTE),
                                 DTor.getDestructorDecl(AC.getASTContext()),
                                 BTE->getExprLoc());
        CurrStates->remove(BTE);
        break;
      }
      
      case CFGElement::AutomaticObjectDtor: {
        const CFGAutomaticObjDtor &DTor = B.castAs<CFGAutomaticObjDtor>();
        SourceLocation Loc = DTor.getTriggerStmt()->getLocEnd();
        const VarDecl *Var = DTor.getVarDecl();
        
        Visitor.checkCallability(PropagationInfo(Var),
                                 DTor.getDestructorDecl(AC.getASTContext()),
                                 Loc);
        break;
      }
      
      default:
        break;
      }
    }
    
    // TODO: Handle other forms of branching with precision, including while-
    //       and for-loops. (Deferred)
    if (!splitState(CurrBlock, Visitor)) {
      CurrStates->setSource(nullptr);

      if (CurrBlock->succ_size() > 1 ||
          (CurrBlock->succ_size() == 1 &&
           (*CurrBlock->succ_begin())->pred_size() > 1)) {

        auto *RawState = CurrStates.get();

        for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
             SE = CurrBlock->succ_end(); SI != SE; ++SI) {

          if (*SI == nullptr) continue;

          if (BlockInfo.isBackEdge(CurrBlock, *SI)) {
            BlockInfo.borrowInfo(*SI)->intersectAtLoopHead(
                *SI, CurrBlock, RawState, WarningsHandler);

            if (BlockInfo.allBackEdgesVisited(CurrBlock, *SI))
              BlockInfo.discardInfo(*SI);
          } else {
            BlockInfo.addInfo(*SI, RawState, CurrStates);
          }
        }

        CurrStates = nullptr;
      }
    }
    
    if (CurrBlock == &AC.getCFG()->getExit() &&
        D->getCallResultType()->isVoidType())
      CurrStates->checkParamsForReturnTypestate(D->getLocation(),
                                                WarningsHandler);
  } // End of block iterator.
  
  // Delete the last existing state map.
  CurrStates = nullptr;

  WarningsHandler.emitDiagnostics();
}
}} // end namespace clang::consumed
