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