//== CheckerContext.h - Context info for path-sensitive checkers--*- C++ -*--=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file defines CheckerContext that provides contextual info for
// path-sensitive checkers.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERCONTEXT_H

#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"

namespace clang {
namespace ento {

class CheckerContext {
  ExprEngine &Eng;
  /// The current exploded(symbolic execution) graph node.
  ExplodedNode *Pred;
  /// The flag is true if the (state of the execution) has been modified
  /// by the checker using this context. For example, a new transition has been
  /// added or a bug report issued.
  bool Changed;
  /// The tagged location, which is used to generate all new nodes.
  const ProgramPoint Location;
  NodeBuilder &NB;

public:
  /// If we are post visiting a call, this flag will be set if the
  /// call was inlined.  In all other cases it will be false.
  const bool wasInlined;

  CheckerContext(NodeBuilder &builder,
                 ExprEngine &eng,
                 ExplodedNode *pred,
                 const ProgramPoint &loc,
                 bool wasInlined = false)
    : Eng(eng),
      Pred(pred),
      Changed(false),
      Location(loc),
      NB(builder),
      wasInlined(wasInlined) {
    assert(Pred->getState() &&
           "We should not call the checkers on an empty state.");
  }

  AnalysisManager &getAnalysisManager() {
    return Eng.getAnalysisManager();
  }

  ConstraintManager &getConstraintManager() {
    return Eng.getConstraintManager();
  }

  StoreManager &getStoreManager() {
    return Eng.getStoreManager();
  }

  /// Returns the previous node in the exploded graph, which includes
  /// the state of the program before the checker ran. Note, checkers should
  /// not retain the node in their state since the nodes might get invalidated.
  ExplodedNode *getPredecessor() { return Pred; }
  const ProgramStateRef &getState() const { return Pred->getState(); }

  /// Check if the checker changed the state of the execution; ex: added
  /// a new transition or a bug report.
  bool isDifferent() { return Changed; }

  /// Returns the number of times the current block has been visited
  /// along the analyzed path.
  unsigned blockCount() const {
    return NB.getContext().blockCount();
  }

  ASTContext &getASTContext() {
    return Eng.getContext();
  }

  const LangOptions &getLangOpts() const {
    return Eng.getContext().getLangOpts();
  }

  const LocationContext *getLocationContext() const {
    return Pred->getLocationContext();
  }

  const StackFrameContext *getStackFrame() const {
    return Pred->getStackFrame();
  }

  /// Return true if the current LocationContext has no caller context.
  bool inTopFrame() const { return getLocationContext()->inTopFrame();  }

  BugReporter &getBugReporter() {
    return Eng.getBugReporter();
  }

  const SourceManager &getSourceManager() {
    return getBugReporter().getSourceManager();
  }

  Preprocessor &getPreprocessor() { return getBugReporter().getPreprocessor(); }

  SValBuilder &getSValBuilder() {
    return Eng.getSValBuilder();
  }

  SymbolManager &getSymbolManager() {
    return getSValBuilder().getSymbolManager();
  }

  ProgramStateManager &getStateManager() {
    return Eng.getStateManager();
  }

  AnalysisDeclContext *getCurrentAnalysisDeclContext() const {
    return Pred->getLocationContext()->getAnalysisDeclContext();
  }

  /// Get the blockID.
  unsigned getBlockID() const {
    return NB.getContext().getBlock()->getBlockID();
  }

  /// If the given node corresponds to a PostStore program point,
  /// retrieve the location region as it was uttered in the code.
  ///
  /// This utility can be useful for generating extensive diagnostics, for
  /// example, for finding variables that the given symbol was assigned to.
  static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) {
    ProgramPoint L = N->getLocation();
    if (Optional<PostStore> PSL = L.getAs<PostStore>())
      return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
    return nullptr;
  }

  /// Get the value of arbitrary expressions at this point in the path.
  SVal getSVal(const Stmt *S) const {
    return Pred->getSVal(S);
  }

  /// Returns true if the value of \p E is greater than or equal to \p
  /// Val under unsigned comparison
  bool isGreaterOrEqual(const Expr *E, unsigned long long Val);

  /// Returns true if the value of \p E is negative.
  bool isNegative(const Expr *E);

  /// Generates a new transition in the program state graph
  /// (ExplodedGraph). Uses the default CheckerContext predecessor node.
  ///
  /// @param State The state of the generated node. If not specified, the state
  ///        will not be changed, but the new node will have the checker's tag.
  /// @param Tag The tag is used to uniquely identify the creation site. If no
  ///        tag is specified, a default tag, unique to the given checker,
  ///        will be used. Tags are used to prevent states generated at
  ///        different sites from caching out.
  ExplodedNode *addTransition(ProgramStateRef State = nullptr,
                              const ProgramPointTag *Tag = nullptr) {
    return addTransitionImpl(State ? State : getState(), false, nullptr, Tag);
  }

  /// Generates a new transition with the given predecessor.
  /// Allows checkers to generate a chain of nodes.
  ///
  /// @param State The state of the generated node.
  /// @param Pred The transition will be generated from the specified Pred node
  ///             to the newly generated node.
  /// @param Tag The tag to uniquely identify the creation site.
  ExplodedNode *addTransition(ProgramStateRef State, ExplodedNode *Pred,
                              const ProgramPointTag *Tag = nullptr) {
    return addTransitionImpl(State, false, Pred, Tag);
  }

  /// Generate a sink node. Generating a sink stops exploration of the
  /// given path. To create a sink node for the purpose of reporting an error,
  /// checkers should use generateErrorNode() instead.
  ExplodedNode *generateSink(ProgramStateRef State, ExplodedNode *Pred,
                             const ProgramPointTag *Tag = nullptr) {
    return addTransitionImpl(State ? State : getState(), true, Pred, Tag);
  }

  /// Add a sink node to the current path of execution, halting analysis.
  void addSink(ProgramStateRef State = nullptr,
               const ProgramPointTag *Tag = nullptr) {
    if (!State)
      State = getState();
    addTransition(State, generateSink(State, getPredecessor()));
  }

  /// Generate a transition to a node that will be used to report
  /// an error. This node will be a sink. That is, it will stop exploration of
  /// the given path.
  ///
  /// @param State The state of the generated node.
  /// @param Tag The tag to uniquely identify the creation site. If null,
  ///        the default tag for the checker will be used.
  ExplodedNode *generateErrorNode(ProgramStateRef State = nullptr,
                                  const ProgramPointTag *Tag = nullptr) {
    return generateSink(State, Pred,
                       (Tag ? Tag : Location.getTag()));
  }

  /// Generate a transition to a node that will be used to report
  /// an error. This node will not be a sink. That is, exploration will
  /// continue along this path.
  ///
  /// @param State The state of the generated node.
  /// @param Tag The tag to uniquely identify the creation site. If null,
  ///        the default tag for the checker will be used.
  ExplodedNode *
  generateNonFatalErrorNode(ProgramStateRef State = nullptr,
                            const ProgramPointTag *Tag = nullptr) {
    return addTransition(State, (Tag ? Tag : Location.getTag()));
  }

  /// Generate a transition to a node that will be used to report
  /// an error. This node will not be a sink. That is, exploration will
  /// continue along this path.
  ///
  /// @param State The state of the generated node.
  /// @param Pred The transition will be generated from the specified Pred node
  ///             to the newly generated node.
  /// @param Tag The tag to uniquely identify the creation site. If null,
  ///        the default tag for the checker will be used.
  ExplodedNode *
  generateNonFatalErrorNode(ProgramStateRef State,
                            ExplodedNode *Pred,
                            const ProgramPointTag *Tag = nullptr) {
    return addTransition(State, Pred, (Tag ? Tag : Location.getTag()));
  }

  /// Emit the diagnostics report.
  void emitReport(std::unique_ptr<BugReport> R) {
    Changed = true;
    Eng.getBugReporter().emitReport(std::move(R));
  }

  /// Produce a program point tag that displays an additional path note
  /// to the user. This is a lightweight alternative to the
  /// BugReporterVisitor mechanism: instead of visiting the bug report
  /// node-by-node to restore the sequence of events that led to discovering
  /// a bug, you can add notes as you add your transitions.
  ///
  /// @param Cb Callback with 'BugReporterContext &, BugReport &' parameters.
  /// @param IsPrunable Whether the note is prunable. It allows BugReporter
  ///        to omit the note from the report if it would make the displayed
  ///        bug path significantly shorter.
  const NoteTag *getNoteTag(NoteTag::Callback &&Cb, bool IsPrunable = false) {
    return Eng.getNoteTags().makeNoteTag(std::move(Cb), IsPrunable);
  }

  /// A shorthand version of getNoteTag that doesn't require you to accept
  /// the 'BugReporterContext' argument when you don't need it.
  ///
  /// @param Cb Callback only with 'BugReport &' parameter.
  /// @param IsPrunable Whether the note is prunable. It allows BugReporter
  ///        to omit the note from the report if it would make the displayed
  ///        bug path significantly shorter.
  const NoteTag
  *getNoteTag(std::function<std::string(PathSensitiveBugReport &)> &&Cb,
              bool IsPrunable = false) {
    return getNoteTag(
        [Cb](BugReporterContext &,
             PathSensitiveBugReport &BR) { return Cb(BR); },
        IsPrunable);
  }

  /// A shorthand version of getNoteTag that doesn't require you to accept
  /// the arguments when you don't need it.
  ///
  /// @param Cb Callback without parameters.
  /// @param IsPrunable Whether the note is prunable. It allows BugReporter
  ///        to omit the note from the report if it would make the displayed
  ///        bug path significantly shorter.
  const NoteTag *getNoteTag(std::function<std::string()> &&Cb,
                            bool IsPrunable = false) {
    return getNoteTag([Cb](BugReporterContext &,
                           PathSensitiveBugReport &) { return Cb(); },
                      IsPrunable);
  }

  /// A shorthand version of getNoteTag that accepts a plain note.
  ///
  /// @param Note The note.
  /// @param IsPrunable Whether the note is prunable. It allows BugReporter
  ///        to omit the note from the report if it would make the displayed
  ///        bug path significantly shorter.
  const NoteTag *getNoteTag(StringRef Note, bool IsPrunable = false) {
    return getNoteTag(
        [Note](BugReporterContext &,
               PathSensitiveBugReport &) { return std::string(Note); },
        IsPrunable);
  }

  /// A shorthand version of getNoteTag that accepts a lambda with stream for
  /// note.
  ///
  /// @param Cb Callback with 'BugReport &' and 'llvm::raw_ostream &'.
  /// @param IsPrunable Whether the note is prunable. It allows BugReporter
  ///        to omit the note from the report if it would make the displayed
  ///        bug path significantly shorter.
  const NoteTag *getNoteTag(
      std::function<void(PathSensitiveBugReport &BR, llvm::raw_ostream &OS)> &&Cb,
      bool IsPrunable = false) {
    return getNoteTag(
        [Cb](PathSensitiveBugReport &BR) -> std::string {
          llvm::SmallString<128> Str;
          llvm::raw_svector_ostream OS(Str);
          Cb(BR, OS);
          return std::string(OS.str());
        },
        IsPrunable);
  }

  /// Returns the word that should be used to refer to the declaration
  /// in the report.
  StringRef getDeclDescription(const Decl *D);

  /// Get the declaration of the called function (path-sensitive).
  const FunctionDecl *getCalleeDecl(const CallExpr *CE) const;

  /// Get the name of the called function (path-sensitive).
  StringRef getCalleeName(const FunctionDecl *FunDecl) const;

  /// Get the identifier of the called function (path-sensitive).
  const IdentifierInfo *getCalleeIdentifier(const CallExpr *CE) const {
    const FunctionDecl *FunDecl = getCalleeDecl(CE);
    if (FunDecl)
      return FunDecl->getIdentifier();
    else
      return nullptr;
  }

  /// Get the name of the called function (path-sensitive).
  StringRef getCalleeName(const CallExpr *CE) const {
    const FunctionDecl *FunDecl = getCalleeDecl(CE);
    return getCalleeName(FunDecl);
  }

  /// Returns true if the callee is an externally-visible function in the
  /// top-level namespace, such as \c malloc.
  ///
  /// If a name is provided, the function must additionally match the given
  /// name.
  ///
  /// Note that this deliberately excludes C++ library functions in the \c std
  /// namespace, but will include C library functions accessed through the
  /// \c std namespace. This also does not check if the function is declared
  /// as 'extern "C"', or if it uses C++ name mangling.
  static bool isCLibraryFunction(const FunctionDecl *FD,
                                 StringRef Name = StringRef());

  /// Depending on wither the location corresponds to a macro, return
  /// either the macro name or the token spelling.
  ///
  /// This could be useful when checkers' logic depends on whether a function
  /// is called with a given macro argument. For example:
  ///   s = socket(AF_INET,..)
  /// If AF_INET is a macro, the result should be treated as a source of taint.
  ///
  /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName().
  StringRef getMacroNameOrSpelling(SourceLocation &Loc);

private:
  ExplodedNode *addTransitionImpl(ProgramStateRef State,
                                 bool MarkAsSink,
                                 ExplodedNode *P = nullptr,
                                 const ProgramPointTag *Tag = nullptr) {
    // The analyzer may stop exploring if it sees a state it has previously
    // visited ("cache out"). The early return here is a defensive check to
    // prevent accidental caching out by checker API clients. Unless there is a
    // tag or the client checker has requested that the generated node be
    // marked as a sink, we assume that a client requesting a transition to a
    // state that is the same as the predecessor state has made a mistake. We
    // return the predecessor rather than cache out.
    //
    // TODO: We could potentially change the return to an assertion to alert
    // clients to their mistake, but several checkers (including
    // DereferenceChecker, CallAndMessageChecker, and DynamicTypePropagation)
    // rely upon the defensive behavior and would need to be updated.
    if (!State || (State == Pred->getState() && !Tag && !MarkAsSink))
      return Pred;

    Changed = true;
    const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
    if (!P)
      P = Pred;

    ExplodedNode *node;
    if (MarkAsSink)
      node = NB.generateSink(LocalLoc, State, P);
    else
      node = NB.generateNode(LocalLoc, State, P);
    return node;
  }
};

} // end GR namespace

} // end clang namespace

#endif
