ExprEngine.h revision 769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5
1d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis//===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=// 277349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// 377349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// The LLVM Compiler Infrastructure 477349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// 577349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// This file is distributed under the University of Illinois Open Source 677349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// License. See LICENSE.TXT for details. 777349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// 877349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//===----------------------------------------------------------------------===// 977349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// 10b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek// This file defines a meta-engine for path-sensitive dataflow analysis that 11d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis// is built on CoreEngine, but provides the boilerplate to execute transfer 12b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek// functions and build the ExplodedGraph at the expression level. 1377349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// 1477349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//===----------------------------------------------------------------------===// 1577349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek 16d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis#ifndef LLVM_CLANG_GR_EXPRENGINE 17d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis#define LLVM_CLANG_GR_EXPRENGINE 18d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek 199b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 209b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" 219b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" 229b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" 239b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h" 249b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 25c0c3f5dbc9e78aa53a86c7d5e3eeda23ddad93d6Ted Kremenek#include "clang/AST/Type.h" 26f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff#include "clang/AST/ExprObjC.h" 27bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu#include "clang/AST/ExprCXX.h" 284beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek#include "clang/AST/StmtObjC.h" 2977349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek 301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace clang { 315a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 325a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisclass ObjCForCollectionStmt; 335a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 349ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremeneknamespace ento { 355a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 365e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramerclass AnalysisManager; 375e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramerclass Checker; 38f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff 39d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisclass ExprEngine : public SubEngine { 4025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu AnalysisManager &AMgr; 4125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 42d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis CoreEngine Engine; 431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 44b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// G - the simulation graph. 45031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedGraph& G; 461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 47d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis /// Builder - The current StmtNodeBuilder which is used when building the 48b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// nodes for a given statement. 49d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis StmtNodeBuilder* Builder; 501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 51b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// StateMgr - Object that manages the data for all created states. 524adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek GRStateManager StateMgr; 53cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 54b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// SymMgr - Object that manages the symbol information. 55b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek SymbolManager& SymMgr; 561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 57846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek /// svalBuilder - SValBuilder object that creates SVals from expressions. 58846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek SValBuilder &svalBuilder; 591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 60846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek /// EntryNode - The immediate predecessor node. 61031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNode* EntryNode; 62846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek 63846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek /// CleanedState - The state for EntryNode "cleaned" of all dead 640d093d3005dd583675a45a85bd688063572cc8afTed Kremenek /// variables and symbols (as determined by a liveness analysis). 651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const GRState* CleanedState; 661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 670a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek /// currentStmt - The current block-level statement. 680a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek const Stmt* currentStmt; 691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 70e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek // Obj-C Class Identifiers. 71e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek IdentifierInfo* NSExceptionII; 721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 73e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek // Obj-C Selectors. 74e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek Selector* NSExceptionInstanceRaiseSelectors; 75e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek Selector RaiseSel; 761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7772905cfa81cfd126f322c4173f56d332aac5539eJordy Rose enum CallbackKind { 7872905cfa81cfd126f322c4173f56d332aac5539eJordy Rose PreVisitStmtCallback, 7972905cfa81cfd126f322c4173f56d332aac5539eJordy Rose PostVisitStmtCallback, 80e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek processAssumeCallback, 81c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose EvalRegionChangesCallback 8272905cfa81cfd126f322c4173f56d332aac5539eJordy Rose }; 8372905cfa81cfd126f322c4173f56d332aac5539eJordy Rose 8472905cfa81cfd126f322c4173f56d332aac5539eJordy Rose typedef uint32_t CallbackTag; 8572905cfa81cfd126f322c4173f56d332aac5539eJordy Rose 8672905cfa81cfd126f322c4173f56d332aac5539eJordy Rose /// GetCallbackTag - Create a tag for a certain kind of callback. The 'Sub' 8772905cfa81cfd126f322c4173f56d332aac5539eJordy Rose /// argument can be used to differentiate callbacks that depend on another 8872905cfa81cfd126f322c4173f56d332aac5539eJordy Rose /// value from a small set of possibilities, such as statement classes. 8972905cfa81cfd126f322c4173f56d332aac5539eJordy Rose static inline CallbackTag GetCallbackTag(CallbackKind K, uint32_t Sub = 0) { 9072905cfa81cfd126f322c4173f56d332aac5539eJordy Rose assert(Sub == ((Sub << 8) >> 8) && "Tag sub-kind must fit into 24 bits"); 9172905cfa81cfd126f322c4173f56d332aac5539eJordy Rose return K | (Sub << 8); 9272905cfa81cfd126f322c4173f56d332aac5539eJordy Rose } 9372905cfa81cfd126f322c4173f56d332aac5539eJordy Rose 94094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek typedef llvm::DenseMap<void *, unsigned> CheckerMap; 95b94b81a9ab46c99b00c7ad28c5e1e212c63fc9acZhongxing Xu typedef std::vector<std::pair<void *, Checker*> > CheckersOrdered; 9672905cfa81cfd126f322c4173f56d332aac5539eJordy Rose typedef llvm::DenseMap<CallbackTag, CheckersOrdered *> CheckersOrderedCache; 979e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek 989e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek /// A registration map from checker tag to the index into the 999e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek /// ordered checkers vector. 1009e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek CheckerMap CheckerM; 1019e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek 1029e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek /// An ordered vector of checkers that are called when evaluating 1039e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek /// various expressions and statements. 104094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek CheckersOrdered Checkers; 105ff944a8c481d6c0f1ad2633e4be9bf8b1dd2a09fZhongxing Xu 1069e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek /// A map used for caching the checkers that respond to the callback for 10772905cfa81cfd126f322c4173f56d332aac5539eJordy Rose /// a particular callback tag. 1089e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek CheckersOrderedCache COCache; 1099e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek 1109e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek /// The BugReporter associated with this engine. It is important that 1119e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek /// this object be placed at the very end of member variables so that its 112d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis /// destructor is called before the rest of the ExprEngine is destroyed. 113cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek GRBugReporter BR; 11432a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek 115d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis llvm::OwningPtr<TransferFuncs> TF; 1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 117b22d589e2ccd09cada0bcea136f0966883a8bb11Ted Kremenekpublic: 118d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ExprEngine(AnalysisManager &mgr, TransferFuncs *tf); 119cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 120d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ~ExprEngine(); 1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu void ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) { 123d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis Engine.ExecuteWorkList(L, Steps, 0); 1242ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu } 1252ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu 1262ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu /// Execute the work list with an initial state. Nodes that reaches the exit 1272ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu /// of the function are added into the Dst set, which represent the exit 1282ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu /// state of the function call. 1292ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, 1302ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu const GRState *InitState, 1312ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu ExplodedNodeSet &Dst) { 132d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst); 133b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek } 1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 135b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// getContext - Return the ASTContext associated with this analysis. 136c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu ASTContext& getContext() const { return AMgr.getASTContext(); } 1375032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu 1382ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu virtual AnalysisManager &getAnalysisManager() { return AMgr; } 1391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 140769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerManager &getCheckerManager() const { 141769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return *AMgr.getCheckerManager(); 142769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 143769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 144846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek SValBuilder &getSValBuilder() { return svalBuilder; } 1451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 146d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis TransferFuncs& getTF() { return *TF; } 1471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 148cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BugReporter& getBugReporter() { return BR; } 1491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 150d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis StmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; } 151ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu 152d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis // FIXME: Remove once TransferFuncs is no longer referenced. 153d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis void setTransferFunction(TransferFuncs* tf); 1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 155e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek /// ViewGraph - Visualize the ExplodedGraph created by executing the 156e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek /// simulation. 157ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek void ViewGraph(bool trim = false); 1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 159031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu void ViewGraph(ExplodedNode** Beg, ExplodedNode** End); 1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 161b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// getInitialState - Return the initial state used for the root vertex 162b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// in the ExplodedGraph. 16317fd8632dcda97022a51effc24060eacdad9dbe0Zhongxing Xu const GRState* getInitialState(const LocationContext *InitLoc); 1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 165031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedGraph& getGraph() { return G; } 166031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu const ExplodedGraph& getGraph() const { return G; } 16750a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 168ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu template <typename CHECKER> 169094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek void registerCheck(CHECKER *check) { 170094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek unsigned entry = Checkers.size(); 171094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek void *tag = CHECKER::getTag(); 172094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek Checkers.push_back(std::make_pair(tag, check)); 173094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek CheckerM[tag] = entry; 174ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu } 175094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek 176094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek Checker *lookupChecker(void *tag) const; 177ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu 178ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu template <typename CHECKER> 179094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek CHECKER *getChecker() const { 180094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag())); 1815a5d98bc6962dc2d1aaa5e0e522f1bf84273b9c1Ted Kremenek } 1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 183e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek /// processCFGElement - Called by CoreEngine. Used to generate new successor 1849c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu /// nodes by processing the 'effects' of a CFG element. 185e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek void processCFGElement(const CFGElement E, StmtNodeBuilder& builder); 1869c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 187d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis void ProcessStmt(const CFGStmt S, StmtNodeBuilder &builder); 1889c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 189d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis void ProcessInitializer(const CFGInitializer I, StmtNodeBuilder &builder); 1909c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 191d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis void ProcessImplicitDtor(const CFGImplicitDtor D, StmtNodeBuilder &builder); 1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1934ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, 194d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis StmtNodeBuilder &builder); 195d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis void ProcessBaseDtor(const CFGBaseDtor D, StmtNodeBuilder &builder); 196d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis void ProcessMemberDtor(const CFGMemberDtor D, StmtNodeBuilder &builder); 1974ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu void ProcessTemporaryDtor(const CFGTemporaryDtor D, 198d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis StmtNodeBuilder &builder); 1994ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 20027c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek /// Called by CoreEngine when processing the entrance of a CFGBlock. 20127c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek virtual void processCFGBlockEntrance(ExplodedNodeSet &dstNodes, 20227c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek GenericNodeBuilder<BlockEntrance> &nodeBuilder); 20327c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek 204d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis /// ProcessBranch - Called by CoreEngine. Used to generate successor 205b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// nodes by processing the 'effects' of a branch condition. 206e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek void processBranch(const Stmt* Condition, const Stmt* Term, 207d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis BranchNodeBuilder& builder); 2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 209e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek /// processIndirectGoto - Called by CoreEngine. Used to generate successor 210b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// nodes by processing the 'effects' of a computed goto jump. 211e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek void processIndirectGoto(IndirectGotoNodeBuilder& builder); 2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 213d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis /// ProcessSwitch - Called by CoreEngine. Used to generate successor 214b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// nodes by processing the 'effects' of a switch statement. 215e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek void processSwitch(SwitchNodeBuilder& builder); 2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 217d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis /// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path 21811062b118476368fa5b294954713e5df97d8599fTed Kremenek /// nodes when the control reaches the end of a function. 219e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek void processEndOfFunction(EndOfFunctionNodeBuilder& builder); 220102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 221ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek /// Generate the entry node of the callee. 222e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek void processCallEnter(CallEnterNodeBuilder &builder); 223102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 224ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek /// Generate the first post callsite node. 225e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek void processCallExit(CallExitNodeBuilder &builder); 226102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 227d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis /// Called by CoreEngine when the analysis worklist has terminated. 228e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek void processEndWorklist(bool hasWorkRemaining); 229ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek 2309c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek /// evalAssume - Callback function invoked by the ConstraintManager when 23132a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek /// making assumptions about state values. 232e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek const GRState *processAssume(const GRState *state, SVal cond,bool assumption); 2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 234e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek /// wantsRegionChangeUpdate - Called by GRStateManager to determine if a 235e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek /// region change should trigger a processRegionChanges update. 236e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek bool wantsRegionChangeUpdate(const GRState* state); 237c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose 238e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek /// processRegionChanges - Called by GRStateManager whenever a change is made 239c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose /// to the store. Used to update checkers that track region values. 240e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek const GRState* processRegionChanges(const GRState *state, 241c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose const MemRegion * const *Begin, 242c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose const MemRegion * const *End); 243c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose 2442ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu virtual GRStateManager& getStateManager() { return StateMgr; } 24590e72e4106a0c3efa7575e9f9cba0c775bb54552Zhongxing Xu 24690e72e4106a0c3efa7575e9f9cba0c775bb54552Zhongxing Xu StoreManager& getStoreManager() { return StateMgr.getStoreManager(); } 2471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 248a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek ConstraintManager& getConstraintManager() { 249a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek return StateMgr.getConstraintManager(); 250a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek } 2511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 252c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek // FIXME: Remove when we migrate over to just using SValBuilder. 2536297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek BasicValueFactory& getBasicVals() { 2546297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek return StateMgr.getBasicVals(); 2556297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek } 2566297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek const BasicValueFactory& getBasicVals() const { 2576297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek return StateMgr.getBasicVals(); 2586297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek } 2591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 260044b6f0417cb98741f277602fabf5f07ec9a02c0Ted Kremenek // FIXME: Remove when we migrate over to just using ValueManager. 26100a3a5f024ac54088ab887712b292171188064f0Ted Kremenek SymbolManager& getSymbolManager() { return SymMgr; } 26200a3a5f024ac54088ab887712b292171188064f0Ted Kremenek const SymbolManager& getSymbolManager() const { return SymMgr; } 2631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 264bc42c533e7d3d946704a49e242939dd232f33072Tom Care // Functions for external checking of whether we have unfinished work 265d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis bool wasBlockAborted() const { return Engine.wasBlockAborted(); } 266d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); } 267bc42c533e7d3d946704a49e242939dd232f33072Tom Care bool hasWorkRemaining() const { 268d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis return wasBlockAborted() || Engine.getWorkList()->hasWork(); 269bc42c533e7d3d946704a49e242939dd232f33072Tom Care } 270bc42c533e7d3d946704a49e242939dd232f33072Tom Care 271d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis const CoreEngine &getCoreEngine() const { return Engine; } 272bc42c533e7d3d946704a49e242939dd232f33072Tom Care 27305a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenekprotected: 274031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu const GRState* GetState(ExplodedNode* N) { 275846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek return N == EntryNode ? CleanedState : N->getState(); 276512c913a6f93d225faacdb8e20308f5c4065c3ebTed Kremenek } 2771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2781670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekpublic: 2793992a50eea030a2913f1d267554f55ecd00d694cZhongxing Xu ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S, 2803992a50eea030a2913f1d267554f55ecd00d694cZhongxing Xu ExplodedNode* Pred, const GRState* St, 281bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu ProgramPoint::Kind K = ProgramPoint::PostStmtKind, 282bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu const void *tag = 0); 2837b71c1977cccafa23f9ecb3b0b22199e61ae634cZhongxing Xu 2845a5d98bc6962dc2d1aaa5e0e522f1bf84273b9c1Ted Kremenek /// CheckerVisit - Dispatcher for performing checker-specific logic 2855a5d98bc6962dc2d1aaa5e0e522f1bf84273b9c1Ted Kremenek /// at specific statements. 28603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void CheckerVisit(const Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 28772905cfa81cfd126f322c4173f56d332aac5539eJordy Rose CallbackKind Kind); 288a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu 289432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis void CheckerVisitObjCMessage(const ObjCMessage &msg, ExplodedNodeSet &Dst, 290432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis ExplodedNodeSet &Src, bool isPrevisit); 291432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis 292935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu bool CheckerEvalCall(const CallExpr *CE, 293935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu ExplodedNodeSet &Dst, 294935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu ExplodedNode *Pred); 295935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu 296432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis void CheckerEvalNilReceiver(const ObjCMessage &msg, 297a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu ExplodedNodeSet &Dst, 298a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu const GRState *state, 299a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu ExplodedNode *Pred); 300b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek 30179d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek void CheckerVisitBind(const Stmt *StoreE, ExplodedNodeSet &Dst, 30279d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek ExplodedNodeSet &Src, SVal location, SVal val, 30379d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek bool isPrevisit); 304ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu 305b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// Visit - Transfer function logic for all statements. Dispatches to 306b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// other functions that handle specific kinds of statements. 30703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void Visit(const Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst); 3081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 309c5b1bf10133a8ecbfe9e6b3ec92bae84e3d927e8Ted Kremenek /// VisitArraySubscriptExpr - Transfer function for array accesses. 310892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr* Ex, 311892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNode* Pred, 312892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNodeSet& Dst); 3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 314ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek /// VisitAsmStmt - Transfer function logic for inline asm. 31503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitAsmStmt(const AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst); 3161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitAsmStmtHelperOutputs(const AsmStmt* A, 31803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu AsmStmt::const_outputs_iterator I, 31903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu AsmStmt::const_outputs_iterator E, 320031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNode* Pred, ExplodedNodeSet& Dst); 3211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 32203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitAsmStmtHelperInputs(const AsmStmt* A, 32303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu AsmStmt::const_inputs_iterator I, 32403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu AsmStmt::const_inputs_iterator E, 325031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNode* Pred, ExplodedNodeSet& Dst); 326c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek 327c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek /// VisitBlockExpr - Transfer function logic for BlockExprs. 32803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 32903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu ExplodedNodeSet &Dst); 3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 331b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// VisitBinaryOperator - Transfer function logic for binary operators. 33203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode* Pred, 333892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNodeSet& Dst); 334469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek 3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 336de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek /// VisitCall - Transfer function for function calls. 33703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitCall(const CallExpr* CE, ExplodedNode* Pred, 33803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu CallExpr::const_arg_iterator AI, 33903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu CallExpr::const_arg_iterator AE, 340892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNodeSet& Dst); 3411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 342b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// VisitCast - Transfer function logic for all casts (implicit and explicit). 34303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, 344892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNodeSet &Dst); 345e1c2a675e0c089e1f53cbd55d2197a8beaa852aeTed Kremenek 3464f09027385466f1f4c382c80ca77157e2aef97d9Ted Kremenek /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. 34703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitCompoundLiteralExpr(const CompoundLiteralExpr* CL, 348892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNode* Pred, ExplodedNodeSet& Dst); 3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 350892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs. 35103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitCommonDeclRefExpr(const Expr* DR, const NamedDecl *D, 352892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNode* Pred, ExplodedNodeSet& Dst); 35367d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek 354b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// VisitDeclStmt - Transfer function logic for DeclStmts. 35503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitDeclStmt(const DeclStmt* DS, ExplodedNode* Pred, 35603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu ExplodedNodeSet& Dst); 3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 358b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose 35903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitGuardedExpr(const Expr* Ex, const Expr* L, const Expr* R, 36003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu ExplodedNode* Pred, ExplodedNodeSet& Dst); 361c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu 362fcfb503c280ed8c66d428fed911b2846c0f434fcTed Kremenek /// VisitCondInit - Transfer function for handling the initialization 363fcfb503c280ed8c66d428fed911b2846c0f434fcTed Kremenek /// of a condition variable in an IfStmt, SwitchStmt, etc. 36403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitCondInit(const VarDecl *VD, const Stmt *S, ExplodedNode *Pred, 365fcfb503c280ed8c66d428fed911b2846c0f434fcTed Kremenek ExplodedNodeSet& Dst); 36661dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek 36703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred, 368c05f23994720b3eb0a3b3494e7bfcec9e1536c89Ted Kremenek ExplodedNodeSet& Dst); 369c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu 370b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// VisitLogicalExpr - Transfer function logic for '&&', '||' 37103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode* Pred, 372c05f23994720b3eb0a3b3494e7bfcec9e1536c89Ted Kremenek ExplodedNodeSet& Dst); 3731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 374469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek /// VisitMemberExpr - Transfer function for member expressions. 37503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitMemberExpr(const MemberExpr* M, ExplodedNode* Pred, 376892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNodeSet& Dst); 3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3784beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek /// Transfer function logic for ObjCAtSynchronizedStmts. 3794beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, 3804beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst); 3814beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek 38214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E, 38314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis ExplodedNode *Pred, ExplodedNodeSet &Dst); 38414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 385892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek /// Transfer function logic for computing the lvalue of an Objective-C ivar. 386892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr* DR, ExplodedNode* Pred, 387892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNodeSet& Dst); 388af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek 389af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek /// VisitObjCForCollectionStmt - Transfer function logic for 390af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek /// ObjCForCollectionStmt. 39103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitObjCForCollectionStmt(const ObjCForCollectionStmt* S, 39203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu ExplodedNode* Pred, ExplodedNodeSet& Dst); 3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 39403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitObjCForCollectionStmtAux(const ObjCForCollectionStmt* S, 395bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu ExplodedNode* Pred, 396031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNodeSet& Dst, SVal ElementV); 3971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 398469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek /// VisitObjCMessageExpr - Transfer function for ObjC message expressions. 39903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitObjCMessageExpr(const ObjCMessageExpr* ME, ExplodedNode* Pred, 400892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNodeSet& Dst); 4015286e2ddfd8332520de4c076e49991d6fe557adbArgyrios Kyrtzidis void VisitObjCMessage(const ObjCMessage &msg, ExplodedNodeSet &Src, 4025286e2ddfd8332520de4c076e49991d6fe557adbArgyrios Kyrtzidis ExplodedNodeSet& Dst); 4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 40402737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek /// VisitReturnStmt - Transfer function logic for return statements. 40503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitReturnStmt(const ReturnStmt* R, ExplodedNode* Pred, 40603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu ExplodedNodeSet& Dst); 4078ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 4088ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor /// VisitOffsetOfExpr - Transfer function for offsetof. 40903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitOffsetOfExpr(const OffsetOfExpr* Ex, ExplodedNode* Pred, 4108ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor ExplodedNodeSet& Dst); 4111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4120518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl /// VisitSizeOfAlignOfExpr - Transfer function for sizeof. 41303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex, ExplodedNode* Pred, 414031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNodeSet& Dst); 4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 416b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// VisitUnaryOperator - Transfer function logic for unary operators. 41703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode* Pred, 418892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNodeSet& Dst); 419bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu 42003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 421bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu ExplodedNodeSet & Dst); 422d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu 423d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *expr, 424892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst) { 425892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitCXXConstructExpr(expr, 0, Pred, Dst); 426d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu } 427d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu 4287ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu void VisitCXXConstructExpr(const CXXConstructExpr *E, const MemRegion *Dest, 429892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst); 430950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu 431b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu void VisitCXXDestructor(const CXXDestructorDecl *DD, 432b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu const MemRegion *Dest, const Stmt *S, 433b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu ExplodedNode *Pred, ExplodedNodeSet &Dst); 434b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 435950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred, 436950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu ExplodedNodeSet &Dst); 437950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu 4386a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *C, 4396a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski ExplodedNode *Pred, ExplodedNodeSet &Dst); 4406a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski 44103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 442856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu ExplodedNodeSet &Dst); 443856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu 44403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, 4456b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu ExplodedNodeSet &Dst); 4466b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu 4477ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu void VisitAggExpr(const Expr *E, const MemRegion *Dest, ExplodedNode *Pred, 4487b71c1977cccafa23f9ecb3b0b22199e61ae634cZhongxing Xu ExplodedNodeSet &Dst); 4497b71c1977cccafa23f9ecb3b0b22199e61ae634cZhongxing Xu 450bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu /// Create a C++ temporary object for an rvalue. 45103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred, 452bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu ExplodedNodeSet &Dst); 453bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu 4548e18c1b840882d26039503629d7e4ad4822f3bdaZhongxing Xu /// Synthesize CXXThisRegion. 4559dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu const CXXThisRegion *getCXXThisRegion(const CXXRecordDecl *RD, 4568e18c1b840882d26039503629d7e4ad4822f3bdaZhongxing Xu const StackFrameContext *SFC); 4578e18c1b840882d26039503629d7e4ad4822f3bdaZhongxing Xu 45832303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu const CXXThisRegion *getCXXThisRegion(const CXXMethodDecl *decl, 45932303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu const StackFrameContext *frameCtx); 46032303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu 461b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu /// Evaluate arguments with a work list algorithm. 4629c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek void evalArguments(ConstExprIterator AI, ConstExprIterator AE, 463b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu const FunctionProtoType *FnType, 46482c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski ExplodedNode *Pred, ExplodedNodeSet &Dst, 46582c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski bool FstArgAsLValue = false); 466b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu 4676a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski /// Evaluate method call itself. Used for CXXMethodCallExpr and 4686a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski /// CXXOperatorCallExpr. 4699c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek void evalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD, 4706a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski const Expr *ThisExpr, ExplodedNode *Pred, 4716a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski ExplodedNodeSet &Src, ExplodedNodeSet &Dst); 4726a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski 4739c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek /// evalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic 47448af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) 47548af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek /// with those assumptions. 4769c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek void evalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src, 47703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const Expr *Ex); 4781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4799c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal evalMinus(SVal X) { 4809c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X; 481b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek } 4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4839c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal evalComplement(SVal X) { 4849c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek return X.isValid() ? svalBuilder.evalComplement(cast<NonLoc>(X)) : X; 48590e420321f60860f4c4e7a68ca9f7567824b46ecTed Kremenek } 486248072a8b9cd956c4ac63172fc2af09790f7c6a9Zhongxing Xu 4871670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekpublic: 4881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4899c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op, 490cd8f6ac9b613e1fe962ebf9c87d822ce765275e6Ted Kremenek NonLoc L, NonLoc R, QualType T) { 4919c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek return svalBuilder.evalBinOpNN(state, op, L, R, T); 4926297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek } 49310c16657eec144def180ee53d1e0249c9ed2b3b5Ted Kremenek 4949c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op, 495cd8f6ac9b613e1fe962ebf9c87d822ce765275e6Ted Kremenek NonLoc L, SVal R, QualType T) { 4969c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R; 497b640b3b5dfccaf259967cb2cb6755c9aa20d4423Ted Kremenek } 4981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4999c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal evalBinOp(const GRState *ST, BinaryOperator::Opcode Op, 500ff4264dae31cf42807b64ecc114906b0b835690aTed Kremenek SVal LHS, SVal RHS, QualType T) { 5019c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T); 502ff4264dae31cf42807b64ecc114906b0b835690aTed Kremenek } 5035b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 5041670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekprotected: 505432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis void evalObjCMessage(ExplodedNodeSet& Dst, const ObjCMessage &msg, 506432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis ExplodedNode* Pred, const GRState *state) { 507d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis assert (Builder && "StmtNodeBuilder must be defined."); 508432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis getTF().evalObjCMessage(Dst, *this, *Builder, msg, Pred, state); 509de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek } 5101670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek 51103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const GRState* MarkBranch(const GRState* St, const Stmt* Terminator, 5121670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek bool branchTaken); 5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5149c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek /// evalBind - Handle the semantics of binding a value to a specific location. 5159c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek /// This method is used by evalStore, VisitDeclStmt, and others. 5169c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek void evalBind(ExplodedNodeSet& Dst, const Stmt* StoreE, ExplodedNode* Pred, 517f6f56d4fc8ebce17e7b83eb2c35f57a055c22283Ted Kremenek const GRState* St, SVal location, SVal Val, 518f6f56d4fc8ebce17e7b83eb2c35f57a055c22283Ted Kremenek bool atDeclInit = false); 5191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5201670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekpublic: 521b4b817d704287836b52b34369009e682f208aa2bTed Kremenek // FIXME: 'tag' should be removed, and a LocationContext should be used 522b4b817d704287836b52b34369009e682f208aa2bTed Kremenek // instead. 523834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan // FIXME: Comment on the meaning of the arguments, when 'St' may not 524834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan // be the same as Pred->state, and when 'location' may not be the 525834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan // same as state->getLValue(Ex). 526834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan /// Simulate a read of the result of Ex. 5279c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek void evalLoad(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred, 528652be346f74feba027bcbdeb6a3e3f4755a0e62cZhongxing Xu const GRState* St, SVal location, const void *tag = 0, 529652be346f74feba027bcbdeb6a3e3f4755a0e62cZhongxing Xu QualType LoadTy = QualType()); 5301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 531b4b817d704287836b52b34369009e682f208aa2bTed Kremenek // FIXME: 'tag' should be removed, and a LocationContext should be used 532b4b817d704287836b52b34369009e682f208aa2bTed Kremenek // instead. 5339c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek void evalStore(ExplodedNodeSet& Dst, const Expr* AssignE, const Expr* StoreE, 534b4b817d704287836b52b34369009e682f208aa2bTed Kremenek ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val, 5351670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek const void *tag = 0); 536834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wanprivate: 5379c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek void evalLoadCommon(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred, 538852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek const GRState* St, SVal location, const void *tag, 539852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek QualType LoadTy); 540852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 541852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // FIXME: 'tag' should be removed, and a LocationContext should be used 542852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // instead. 5439c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek void evalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode* Pred, 544852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek const GRState* St, SVal location, 545852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek const void *tag, bool isLoad); 5461c625f25055331bf76ab5479a8060d2b0f61e8b8Zhongxing Xu 5471c625f25055331bf76ab5479a8060d2b0f61e8b8Zhongxing Xu bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred); 548b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek}; 5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 55065423aeb996a296cf2964f136ce4a4a937bd1687Zhongxing Xu} // end ento namespace 5515a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 552c0c3f5dbc9e78aa53a86c7d5e3eeda23ddad93d6Ted Kremenek} // end clang namespace 553c0c3f5dbc9e78aa53a86c7d5e3eeda23ddad93d6Ted Kremenek 554d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek#endif 555