//==- UninitializedValues.cpp - Find Uninitialized Values -------*- C++ --*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements Uninitialized Values analysis for source-level CFGs.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/Analyses/UninitializedValues.h"
#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
#include "clang/Analysis/LocalCheckers.h"
#include "clang/Analysis/AnalysisDiagnostic.h"
#include "clang/AST/ASTContext.h"
#include "clang/Analysis/FlowSensitive/DataflowSolver.h"
#include "llvm/Support/Compiler.h"

#include "llvm/ADT/SmallPtrSet.h"

using namespace clang;

//===----------------------------------------------------------------------===//
// Dataflow initialization logic.
//===----------------------------------------------------------------------===//      

namespace {

class VISIBILITY_HIDDEN RegisterDecls
  : public CFGRecStmtDeclVisitor<RegisterDecls> {  

  UninitializedValues::AnalysisDataTy& AD;
public:
  RegisterDecls(UninitializedValues::AnalysisDataTy& ad) :  AD(ad) {}
  
  void VisitVarDecl(VarDecl* VD) { AD.Register(VD); }
  CFG& getCFG() { return AD.getCFG(); }
};
  
} // end anonymous namespace

void UninitializedValues::InitializeValues(const CFG& cfg) {
  RegisterDecls R(getAnalysisData());
  cfg.VisitBlockStmts(R);
}

//===----------------------------------------------------------------------===//
// Transfer functions.
//===----------------------------------------------------------------------===//      

namespace {
class VISIBILITY_HIDDEN TransferFuncs
  : public CFGStmtVisitor<TransferFuncs,bool> {
    
  UninitializedValues::ValTy V;
  UninitializedValues::AnalysisDataTy& AD;
public:
  TransferFuncs(UninitializedValues::AnalysisDataTy& ad) : AD(ad) {}
  
  UninitializedValues::ValTy& getVal() { return V; }
  CFG& getCFG() { return AD.getCFG(); }
  
  void SetTopValue(UninitializedValues::ValTy& X) {
    X.setDeclValues(AD);
    X.resetBlkExprValues(AD);
  }
    
  bool VisitDeclRefExpr(DeclRefExpr* DR);
  bool VisitBinaryOperator(BinaryOperator* B);
  bool VisitUnaryOperator(UnaryOperator* U);
  bool VisitStmt(Stmt* S);
  bool VisitCallExpr(CallExpr* C);
  bool VisitDeclStmt(DeclStmt* D);
  bool VisitConditionalOperator(ConditionalOperator* C);
  bool BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt* S);
  
  bool Visit(Stmt *S);
  bool BlockStmt_VisitExpr(Expr* E);
    
  void VisitTerminator(CFGBlock* B) { }
};
  
static const bool Initialized = false;
static const bool Uninitialized = true;  

bool TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
  
  if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
    if (VD->isBlockVarDecl()) {
      
      if (AD.Observer)
        AD.Observer->ObserveDeclRefExpr(V, AD, DR, VD);
     
      // Pseudo-hack to prevent cascade of warnings.  If an accessed variable
      // is uninitialized, then we are already going to flag a warning for
      // this variable, which a "source" of uninitialized values.
      // We can otherwise do a full "taint" of uninitialized values.  The
      // client has both options by toggling AD.FullUninitTaint.

      if (AD.FullUninitTaint)
        return V(VD,AD);
    }
  
  return Initialized;
}

static VarDecl* FindBlockVarDecl(Expr* E) {
  
  // Blast through casts and parentheses to find any DeclRefExprs that
  // refer to a block VarDecl.
  
  if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
    if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))      
      if (VD->isBlockVarDecl()) return VD;

  return NULL;
}

bool TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {

  if (VarDecl* VD = FindBlockVarDecl(B->getLHS()))
    if (B->isAssignmentOp()) {
      if (B->getOpcode() == BinaryOperator::Assign)
        return V(VD,AD) = Visit(B->getRHS());
      else // Handle +=, -=, *=, etc.  We do want '&', not '&&'.
        return V(VD,AD) = Visit(B->getLHS()) & Visit(B->getRHS());
    }

  return VisitStmt(B);
}

bool TransferFuncs::VisitDeclStmt(DeclStmt* S) {
  for (DeclStmt::decl_iterator I=S->decl_begin(), E=S->decl_end(); I!=E; ++I) {
    VarDecl *VD = dyn_cast<VarDecl>(*I);
    if (VD && VD->isBlockVarDecl()) {
      if (Stmt* I = VD->getInit()) 
        V(VD,AD) = AD.FullUninitTaint ? V(cast<Expr>(I),AD) : Initialized;
      else {
        // Special case for declarations of array types.  For things like:
        //
        //  char x[10];
        //
        // we should treat "x" as being initialized, because the variable
        // "x" really refers to the memory block.  Clearly x[1] is
        // uninitialized, but expressions like "(char *) x" really do refer to 
        // an initialized value.  This simple dataflow analysis does not reason 
        // about the contents of arrays, although it could be potentially
        // extended to do so if the array were of constant size.
        if (VD->getType()->isArrayType())
          V(VD,AD) = Initialized;
        else        
          V(VD,AD) = Uninitialized;
      }
    }
  }
  return Uninitialized; // Value is never consumed.
}
  
bool TransferFuncs::VisitCallExpr(CallExpr* C) {
  VisitChildren(C);
  return Initialized;
}

bool TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
  switch (U->getOpcode()) {
    case UnaryOperator::AddrOf: {
      VarDecl* VD = FindBlockVarDecl(U->getSubExpr());
      if (VD && VD->isBlockVarDecl())
        return V(VD,AD) = Initialized;
      break;
    }
    
    default:
      break;
  }

  return Visit(U->getSubExpr());
}
  
bool
TransferFuncs::BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {
  // This represents a use of the 'collection'
  bool x = Visit(S->getCollection());

  if (x == Uninitialized)
    return Uninitialized;

  // This represents an initialization of the 'element' value.
  Stmt* Element = S->getElement();
  VarDecl* VD = 0;

  if (DeclStmt* DS = dyn_cast<DeclStmt>(Element))
    VD = cast<VarDecl>(DS->getSolitaryDecl());
  else {
    Expr* ElemExpr = cast<Expr>(Element)->IgnoreParens();

    // Initialize the value of the reference variable.
    if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(ElemExpr))
      VD = cast<VarDecl>(DR->getDecl());
    else
      return Visit(ElemExpr);
  }
      
  V(VD,AD) = Initialized;
  return Initialized;
}
  
  
bool TransferFuncs::VisitConditionalOperator(ConditionalOperator* C) {
  Visit(C->getCond());

  bool rhsResult = Visit(C->getRHS());
  // Handle the GNU extension for missing LHS.
  if (Expr *lhs = C->getLHS())
    return Visit(lhs) & rhsResult; // Yes: we want &, not &&.
  else
    return rhsResult;
}

bool TransferFuncs::VisitStmt(Stmt* S) {
  bool x = Initialized;

  // We don't stop at the first subexpression that is Uninitialized because
  // evaluating some subexpressions may result in propogating "Uninitialized"
  // or "Initialized" to variables referenced in the other subexpressions.
  for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I)
    if (*I && Visit(*I) == Uninitialized) x = Uninitialized;
  
  return x;
}
  
bool TransferFuncs::Visit(Stmt *S) {
  if (AD.isTracked(static_cast<Expr*>(S))) return V(static_cast<Expr*>(S),AD);
  else return static_cast<CFGStmtVisitor<TransferFuncs,bool>*>(this)->Visit(S);
}

bool TransferFuncs::BlockStmt_VisitExpr(Expr* E) {
  bool x = static_cast<CFGStmtVisitor<TransferFuncs,bool>*>(this)->Visit(E);  
  if (AD.isTracked(E)) V(E,AD) = x;
  return x;
}
  
} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Merge operator.
//
//  In our transfer functions we take the approach that any
//  combination of uninitialized values, e.g.
//      Uninitialized + ___ = Uninitialized.
//
//  Merges take the same approach, preferring soundness.  At a confluence point,
//  if any predecessor has a variable marked uninitialized, the value is
//  uninitialized at the confluence point.
//===----------------------------------------------------------------------===//      

namespace {
  typedef StmtDeclBitVector_Types::Union Merge;
  typedef DataflowSolver<UninitializedValues,TransferFuncs,Merge> Solver;
}

//===----------------------------------------------------------------------===//
// Uninitialized values checker.   Scan an AST and flag variable uses
//===----------------------------------------------------------------------===//      

UninitializedValues_ValueTypes::ObserverTy::~ObserverTy() {}

namespace {
class VISIBILITY_HIDDEN UninitializedValuesChecker
  : public UninitializedValues::ObserverTy {
    
  ASTContext &Ctx;
  Diagnostic &Diags;
  llvm::SmallPtrSet<VarDecl*,10> AlreadyWarned;
  
public:
  UninitializedValuesChecker(ASTContext &ctx, Diagnostic &diags)
    : Ctx(ctx), Diags(diags) {}
    
  virtual void ObserveDeclRefExpr(UninitializedValues::ValTy& V,
                                  UninitializedValues::AnalysisDataTy& AD,
                                  DeclRefExpr* DR, VarDecl* VD) {

    assert ( AD.isTracked(VD) && "Unknown VarDecl.");
    
    if (V(VD,AD) == Uninitialized)
      if (AlreadyWarned.insert(VD))
        Diags.Report(Ctx.getFullLoc(DR->getSourceRange().getBegin()),
                     diag::warn_uninit_val);
  }
};
} // end anonymous namespace

namespace clang {
void CheckUninitializedValues(CFG& cfg, ASTContext &Ctx, Diagnostic &Diags,
                              bool FullUninitTaint) {
  
  // Compute the uninitialized values information.
  UninitializedValues U(cfg);
  U.getAnalysisData().FullUninitTaint = FullUninitTaint;
  Solver S(U);
  S.runOnCFG(cfg);
  
  // Scan for DeclRefExprs that use uninitialized values.
  UninitializedValuesChecker Observer(Ctx,Diags);
  U.getAnalysisData().Observer = &Observer;
  S.runOnAllBlocks(cfg);
}
} // end namespace clang
