diff options
Diffstat (limited to 'include/clang/Analysis/PathSensitive/Checker.h')
| -rw-r--r-- | include/clang/Analysis/PathSensitive/Checker.h | 74 | 
1 files changed, 54 insertions, 20 deletions
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h index 91a4b6d1b1eb..a625a7a25690 100644 --- a/include/clang/Analysis/PathSensitive/Checker.h +++ b/include/clang/Analysis/PathSensitive/Checker.h @@ -39,7 +39,7 @@ class CheckerContext {    SaveAndRestore<const void*> OldTag;    SaveAndRestore<ProgramPoint::Kind> OldPointKind;    SaveOr OldHasGen; -  const GRState *state; +  const GRState *ST;    const Stmt *statement;    const unsigned size;    bool DoneEvaluating; // FIXME: This is not a permanent API change. @@ -53,22 +53,14 @@ public:        OldTag(B.Tag, tag),        OldPointKind(B.PointKind, K),        OldHasGen(B.HasGeneratedNode), -      state(st), statement(stmt), size(Dst.size()), -      DoneEvaluating(false) {} +      ST(st), statement(stmt), size(Dst.size()) {}    ~CheckerContext(); -   -  // FIXME: This were added to support CallAndMessageChecker to indicating -  // to GRExprEngine to "stop evaluating" a message expression under certain -  // cases.  This is *not* meant to be a permanent API change, and was added -  // to aid in the transition of removing logic for checks from GRExprEngine.   -  void setDoneEvaluating() { -    DoneEvaluating = true; -  } -  bool isDoneEvaluating() const { -    return DoneEvaluating; + +  GRExprEngine &getEngine() { +    return Eng;    } -   +    ConstraintManager &getConstraintManager() {        return Eng.getConstraintManager();    } @@ -80,7 +72,7 @@ public:    ExplodedNodeSet &getNodeSet() { return Dst; }    GRStmtNodeBuilder &getNodeBuilder() { return B; }    ExplodedNode *&getPredecessor() { return Pred; } -  const GRState *getState() { return state ? state : B.GetState(Pred); } +  const GRState *getState() { return ST ? ST : B.GetState(Pred); }    ASTContext &getASTContext() {      return Eng.getContext(); @@ -98,6 +90,10 @@ public:      return Eng.getValueManager();    } +  SValuator &getSValuator() { +    return Eng.getSValuator(); +  } +    ExplodedNode *GenerateNode(bool autoTransition = true) {      assert(statement && "Only transitions with statements currently supported");      ExplodedNode *N = GenerateNodeImpl(statement, getState(), false); @@ -115,6 +111,15 @@ public:      return N;    } +  ExplodedNode *GenerateNode(const GRState *state, ExplodedNode *pred, +                             bool autoTransition = true) { +   assert(statement && "Only transitions with statements currently supported"); +    ExplodedNode *N = GenerateNodeImpl(statement, state, pred, false); +    if (N && autoTransition) +      addTransition(N); +    return N; +  } +    ExplodedNode *GenerateNode(const GRState *state, bool autoTransition = true) {      assert(statement && "Only transitions with statements currently supported");      ExplodedNode *N = GenerateNodeImpl(statement, state, false); @@ -138,8 +143,7 @@ public:    void addTransition(const GRState *state) {      assert(state); -    if (state != getState() ||  -        (state && state != B.GetState(Pred))) +    if (state != getState() || (ST && ST != B.GetState(Pred)))        GenerateNode(state, true);      else        Dst.Add(Pred); @@ -157,7 +161,14 @@ private:        node->markAsSink();      return node;    } -   + +  ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state, +                                 ExplodedNode *pred, bool markAsSink) { +   ExplodedNode *node = B.generateNode(stmt, state, pred); +    if (markAsSink && node) +      node->markAsSink(); +    return node; +  }  };  class Checker { @@ -165,7 +176,7 @@ private:    friend class GRExprEngine;    // FIXME: Remove the 'tag' option. -  bool GR_Visit(ExplodedNodeSet &Dst, +  void GR_Visit(ExplodedNodeSet &Dst,                  GRStmtNodeBuilder &Builder,                  GRExprEngine &Eng,                  const Stmt *S, @@ -177,7 +188,22 @@ private:        _PreVisit(C, S);      else        _PostVisit(C, S); -    return C.isDoneEvaluating(); +  } + +  bool GR_EvalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder, +                          GRExprEngine &Eng, const ObjCMessageExpr *ME, +                          ExplodedNode *Pred, const GRState *state, void *tag) { +    CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind, +                     ME, state); +    return EvalNilReceiver(C, ME); +  } + +  bool GR_EvalCallExpr(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder, +                       GRExprEngine &Eng, const CallExpr *CE, +                       ExplodedNode *Pred, void *tag) { +    CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind, +                     CE); +    return EvalCallExpr(C, CE);    }    // FIXME: Remove the 'tag' option. @@ -231,6 +257,14 @@ public:    virtual void VisitBranchCondition(GRBranchNodeBuilder &Builder,                                      GRExprEngine &Eng,                                      Stmt *Condition, void *tag) {} + +  virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) { +    return false; +  } + +  virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE) { +    return false; +  }  };  } // end clang namespace  | 
