// UndefCapturedBlockVarChecker.cpp - Uninitialized captured vars -*- C++ -*-=//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This checker detects blocks that capture uninitialized values.
//
//===----------------------------------------------------------------------===//

#include "GRExprEngineInternalChecks.h"
#include "clang/Checker/PathSensitive/CheckerVisitor.h"
#include "clang/Checker/PathSensitive/GRExprEngine.h"
#include "clang/Checker/BugReporter/BugReporter.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;

namespace {
class UndefCapturedBlockVarChecker
  : public CheckerVisitor<UndefCapturedBlockVarChecker> {
 BugType *BT;

public:
  UndefCapturedBlockVarChecker() : BT(0) {}
  static void *getTag() { static int tag = 0; return &tag; }
  void PostVisitBlockExpr(CheckerContext &C, const BlockExpr *BE);
};
} // end anonymous namespace

void clang::RegisterUndefCapturedBlockVarChecker(GRExprEngine &Eng) {
  Eng.registerCheck(new UndefCapturedBlockVarChecker());
}

static const BlockDeclRefExpr *FindBlockDeclRefExpr(const Stmt *S,
                                                    const VarDecl *VD){
  if (const BlockDeclRefExpr *BR = dyn_cast<BlockDeclRefExpr>(S))
    if (BR->getDecl() == VD)
      return BR;

  for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
       I!=E; ++I)
    if (const Stmt *child = *I) {
      const BlockDeclRefExpr *BR = FindBlockDeclRefExpr(child, VD);
      if (BR)
        return BR;
    }

  return NULL;
}

void
UndefCapturedBlockVarChecker::PostVisitBlockExpr(CheckerContext &C,
                                                 const BlockExpr *BE) {
  if (!BE->hasBlockDeclRefExprs())
    return;

  const GRState *state = C.getState();
  const BlockDataRegion *R =
    cast<BlockDataRegion>(state->getSVal(BE).getAsRegion());

  BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
                                            E = R->referenced_vars_end();

  for (; I != E; ++I) {
    // This VarRegion is the region associated with the block; we need
    // the one associated with the encompassing context.
    const VarRegion *VR = *I;
    const VarDecl *VD = VR->getDecl();

    if (VD->getAttr<BlocksAttr>() || !VD->hasLocalStorage())
      continue;

    // Get the VarRegion associated with VD in the local stack frame.
    const LocationContext *LC = C.getPredecessor()->getLocationContext();
    VR = C.getValueManager().getRegionManager().getVarRegion(VD, LC);

    if (state->getSVal(VR).isUndef())
      if (ExplodedNode *N = C.GenerateSink()) {
        if (!BT)
          BT = new BuiltinBug("Captured block variable is uninitialized");

        // Generate a bug report.
        llvm::SmallString<128> buf;
        llvm::raw_svector_ostream os(buf);

        os << "Variable '" << VD->getName() << "' is captured by block with "
              "a garbage value";

        EnhancedBugReport *R = new EnhancedBugReport(*BT, os.str(), N);
        if (const Expr *Ex = FindBlockDeclRefExpr(BE->getBody(), VD))
          R->addRange(Ex->getSourceRange());
        R->addVisitorCreator(bugreporter::registerFindLastStore, VR);
        // need location of block
        C.EmitReport(R);
      }
  }
}
