14c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley//== SubEngine.h - Interface of the subengine of CoreEngine --------*- C++ -*-//
24c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley//
34c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley//                     The LLVM Compiler Infrastructure
44c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley//
54c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley// This file is distributed under the University of Illinois Open Source
64c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley// License. See LICENSE.TXT for details.
74c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley//
84c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley//===----------------------------------------------------------------------===//
94c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley//
104c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley// This file defines the interface of a subengine of the CoreEngine.
114c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley//
124c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley//===----------------------------------------------------------------------===//
134c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley#ifndef LLVM_CLANG_GR_SUBENGINE_H
144c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley#define LLVM_CLANG_GR_SUBENGINE_H
154c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
164c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley#include "clang/Analysis/ProgramPoint.h"
174c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
184c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
194c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
204c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleynamespace clang {
214c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
224c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass CFGBlock;
234c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass CFGElement;
244c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass LocationContext;
254c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass Stmt;
264c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
274c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleynamespace ento {
284c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
294c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleystruct NodeBuilderContext;
304c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass AnalysisManager;
314c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass ExplodedNodeSet;
324c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass ExplodedNode;
334c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass ProgramState;
344c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass ProgramStateManager;
354c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass BlockCounter;
364c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass BranchNodeBuilder;
374c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass IndirectGotoNodeBuilder;
384c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass SwitchNodeBuilder;
394c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass EndOfFunctionNodeBuilder;
404c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass NodeBuilderWithSinks;
414c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass MemRegion;
424c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
434c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleyclass SubEngine {
444c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void anchor();
454c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langleypublic:
464c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual ~SubEngine() {}
474c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
484c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual ProgramStateRef getInitialState(const LocationContext *InitLoc) = 0;
494c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
504c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual AnalysisManager &getAnalysisManager() = 0;
514c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
524c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual ProgramStateManager &getStateManager() = 0;
534c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
544c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// Called by CoreEngine. Used to generate new successor
554c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// nodes by processing the 'effects' of a block-level statement.
564c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void processCFGElement(const CFGElement E, ExplodedNode* Pred,
574c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                                 unsigned StmtIdx, NodeBuilderContext *Ctx)=0;
584c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
594c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// Called by CoreEngine when it starts processing a CFGBlock.  The
604c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// SubEngine is expected to populate dstNodes with new nodes representing
614c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// updated analysis state, or generate no nodes at all if it doesn't.
624c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void processCFGBlockEntrance(const BlockEdge &L,
634c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                                       NodeBuilderWithSinks &nodeBuilder,
644c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                                       ExplodedNode *Pred) = 0;
654c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
664c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// Called by CoreEngine.  Used to generate successor
674c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  ///  nodes by processing the 'effects' of a branch condition.
684c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void processBranch(const Stmt *Condition, const Stmt *Term,
694c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                             NodeBuilderContext& BuilderCtx,
704c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                             ExplodedNode *Pred,
714c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                             ExplodedNodeSet &Dst,
724c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                             const CFGBlock *DstT,
734c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                             const CFGBlock *DstF) = 0;
744c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
754c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// Called by CoreEngine.  Used to processing branching behavior
764c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// at static initalizers.
774c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void processStaticInitializer(const DeclStmt *DS,
784c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                                        NodeBuilderContext& BuilderCtx,
794c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                                        ExplodedNode *Pred,
804c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                                        ExplodedNodeSet &Dst,
814c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                                        const CFGBlock *DstT,
824c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                                        const CFGBlock *DstF) = 0;
834c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
844c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// Called by CoreEngine.  Used to generate successor
854c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// nodes by processing the 'effects' of a computed goto jump.
864c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void processIndirectGoto(IndirectGotoNodeBuilder& builder) = 0;
874c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
884c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// Called by CoreEngine.  Used to generate successor
894c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// nodes by processing the 'effects' of a switch statement.
904c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void processSwitch(SwitchNodeBuilder& builder) = 0;
914c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
924c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// Called by CoreEngine.  Used to generate end-of-path
934c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// nodes when the control reaches the end of a function.
944c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void processEndOfFunction(NodeBuilderContext& BC,
954c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                                    ExplodedNode *Pred) = 0;
964c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
974c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  // Generate the entry node of the callee.
984c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void processCallEnter(CallEnter CE, ExplodedNode *Pred) = 0;
994c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1004c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  // Generate the first post callsite node.
1014c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void processCallExit(ExplodedNode *Pred) = 0;
1024c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1034c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// Called by ConstraintManager. Used to call checker-specific
1044c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// logic for handling assumptions on symbolic values.
1054c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual ProgramStateRef processAssume(ProgramStateRef state,
1064c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                                       SVal cond, bool assumption) = 0;
1074c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1084c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
1094c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  ///  region change should trigger a processRegionChanges update.
1104c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual bool wantsRegionChangeUpdate(ProgramStateRef state) = 0;
1114c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1124c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// processRegionChanges - Called by ProgramStateManager whenever a change is
1134c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// made to the store. Used to update checkers that track region values.
1144c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual ProgramStateRef
1154c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  processRegionChanges(ProgramStateRef state,
1164c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                       const InvalidatedSymbols *invalidated,
1174c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                       ArrayRef<const MemRegion *> ExplicitRegions,
1184c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                       ArrayRef<const MemRegion *> Regions,
1194c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                       const CallEvent *Call) = 0;
1204c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1214c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1224c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  inline ProgramStateRef
1234c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  processRegionChange(ProgramStateRef state,
1244c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                      const MemRegion* MR) {
1254c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley    return processRegionChanges(state, nullptr, MR, MR, nullptr);
1264c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  }
1274c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1284c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual ProgramStateRef
1294c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val) = 0;
1304c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1314c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual ProgramStateRef
1324c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  notifyCheckersOfPointerEscape(ProgramStateRef State,
1334c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                           const InvalidatedSymbols *Invalidated,
1344c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                           ArrayRef<const MemRegion *> ExplicitRegions,
1354c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                           ArrayRef<const MemRegion *> Regions,
1364c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                           const CallEvent *Call,
1374c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                           RegionAndSymbolInvalidationTraits &HTraits) = 0;
1384c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1394c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// printState - Called by ProgramStateManager to print checker-specific data.
1404c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void printState(raw_ostream &Out, ProgramStateRef State,
1414c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley                          const char *NL, const char *Sep) = 0;
1424c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1434c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  /// Called by CoreEngine when the analysis worklist is either empty or the
1444c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  //  maximum number of analysis steps have been reached.
1454c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley  virtual void processEndWorklist(bool hasWorkRemaining) = 0;
1464c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley};
1474c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1484c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley} // end GR namespace
1494c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1504c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley} // end clang namespace
1514c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley
1524c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley#endif
1534c921e1bbcc1d1cd23848e3b11ab2c9f85ee37eaAdam Langley