ExprEngine.h revision da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8
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 1930a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/AST/Expr.h" 2030a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/AST/Type.h" 214ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" 2230a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 239b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 249b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" 2518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 265903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 2730a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" 2877349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek 291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace clang { 305a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 311d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekclass AnalysisDeclContextManager; 32337e4dbc6859589b8878146a88bebf754e916702Ted Kremenekclass CXXCatchStmt; 33c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramerclass CXXConstructExpr; 34c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramerclass CXXDeleteExpr; 35c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramerclass CXXNewExpr; 36c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramerclass CXXTemporaryObjectExpr; 37c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramerclass CXXThisExpr; 38c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramerclass MaterializeTemporaryExpr; 39c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramerclass ObjCAtSynchronizedStmt; 405a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisclass ObjCForCollectionStmt; 41b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek 429ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremeneknamespace ento { 435a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 445e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramerclass AnalysisManager; 45740d490593e0de8732a697c9f77b90ddd463863bJordan Roseclass CallEvent; 4669f87c956b3ac2b80124fd9604af012e1061473aJordan Roseclass SimpleCall; 47bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Roseclass CXXConstructorCall; 48f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff 49d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisclass ExprEngine : public SubEngine { 5075f31c4862643ab09479c979fabf754e7ffe1460Anna Zakspublic: 518a660eb1084294a903f6dcc00bf2fa4e3bc92cfcAnna Zaks /// The modes of inlining, which override the default analysis-wide settings. 5275f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks enum InliningModes { 538a660eb1084294a903f6dcc00bf2fa4e3bc92cfcAnna Zaks /// Follow the default settings for inlining callees. 548a660eb1084294a903f6dcc00bf2fa4e3bc92cfcAnna Zaks Inline_Regular = 0, 558a660eb1084294a903f6dcc00bf2fa4e3bc92cfcAnna Zaks /// Do minimal inlining of callees. 568a660eb1084294a903f6dcc00bf2fa4e3bc92cfcAnna Zaks Inline_Minimal = 0x1 578a660eb1084294a903f6dcc00bf2fa4e3bc92cfcAnna Zaks }; 5875f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks 5975f31c4862643ab09479c979fabf754e7ffe1460Anna Zaksprivate: 6025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu AnalysisManager &AMgr; 61b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek 621d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContextManager &AnalysisDeclContexts; 6325e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu 64d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis CoreEngine Engine; 651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 66b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// G - the simulation graph. 67031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedGraph& G; 681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 69b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// StateMgr - Object that manages the data for all created states. 7018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ProgramStateManager StateMgr; 71cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 72b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// SymMgr - Object that manages the symbol information. 73b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek SymbolManager& SymMgr; 741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 75846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek /// svalBuilder - SValBuilder object that creates SVals from expressions. 76846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek SValBuilder &svalBuilder; 771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7866c486f275531df6362b3511fc3af6563561801bTed Kremenek unsigned int currStmtIdx; 7966c486f275531df6362b3511fc3af6563561801bTed Kremenek const NodeBuilderContext *currBldrCtx; 804ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek 814ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek /// Helper object to determine if an Objective-C message expression 824ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek /// implicitly never returns. 834ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek ObjCNoReturn ObjCNoRet; 8417a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose 8517a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose /// Whether or not GC is enabled in this analysis. 8617a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose bool ObjCGCEnabled; 871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 889e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek /// The BugReporter associated with this engine. It is important that 899e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek /// this object be placed at the very end of member variables so that its 90d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis /// destructor is called before the rest of the ExprEngine is destroyed. 91cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek GRBugReporter BR; 921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 93fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks /// The functions which have been analyzed through inlining. This is owned by 94fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks /// AnalysisConsumer. It can be null. 95fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks SetOfConstDecls *VisitedCallees; 96fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks 9775f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks /// The flag, which specifies the mode of inlining for the engine. 9875f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks InliningModes HowToInline; 9975f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks 100b22d589e2ccd09cada0bcea136f0966883a8bb11Ted Kremenekpublic: 1016a86082f3a06a2dcceaaf63f78a0e52d64bcbaa3Anna Zaks ExprEngine(AnalysisManager &mgr, bool gcEnabled, 102fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks SetOfConstDecls *VisitedCalleesIn, 10375f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks FunctionSummariesTy *FS, 10475f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks InliningModes HowToInlineIn); 105cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 106d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ~ExprEngine(); 1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 108253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks /// Returns true if there is still simulation state on the worklist. 109253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) { 110253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks return Engine.ExecuteWorkList(L, Steps, 0); 1112ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu } 1122ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu 1132ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu /// Execute the work list with an initial state. Nodes that reaches the exit 1142ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu /// of the function are added into the Dst set, which represent the exit 115253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks /// state of the function call. Returns true if there is still simulation 116253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks /// state on the worklist. 117253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, 1188bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef InitState, 1192ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu ExplodedNodeSet &Dst) { 120253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst); 121b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek } 1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 123b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// getContext - Return the ASTContext associated with this analysis. 1249c378f705405d37f49795d5e915989de774fe11fTed Kremenek ASTContext &getContext() const { return AMgr.getASTContext(); } 1255032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu 1262ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu virtual AnalysisManager &getAnalysisManager() { return AMgr; } 1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 128769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerManager &getCheckerManager() const { 129769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return *AMgr.getCheckerManager(); 130769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 131769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 132846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek SValBuilder &getSValBuilder() { return svalBuilder; } 1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 134cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BugReporter& getBugReporter() { return BR; } 1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1361aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks const NodeBuilderContext &getBuilderContext() { 13766c486f275531df6362b3511fc3af6563561801bTed Kremenek assert(currBldrCtx); 13866c486f275531df6362b3511fc3af6563561801bTed Kremenek return *currBldrCtx; 1391aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks } 140ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu 14117a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose bool isObjCGCEnabled() { return ObjCGCEnabled; } 1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 143ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks const Stmt *getStmt() const; 144ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 145ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks void GenerateAutoTransition(ExplodedNode *N); 146af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks void enqueueEndOfPath(ExplodedNodeSet &S); 147af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks void GenerateCallExitNode(ExplodedNode *N); 148ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 149c9963132736782d0c9178c744b3e2307cfb98a08Jordan Rose /// Visualize the ExplodedGraph created by executing the simulation. 150ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek void ViewGraph(bool trim = false); 1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 152c9963132736782d0c9178c744b3e2307cfb98a08Jordan Rose /// Visualize a trimmed ExplodedGraph that only contains paths to the given 153c9963132736782d0c9178c744b3e2307cfb98a08Jordan Rose /// nodes. 154c9963132736782d0c9178c744b3e2307cfb98a08Jordan Rose void ViewGraph(ArrayRef<const ExplodedNode*> Nodes); 1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 156b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// getInitialState - Return the initial state used for the root vertex 157b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// in the ExplodedGraph. 1588bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef getInitialState(const LocationContext *InitLoc); 1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 160031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedGraph& getGraph() { return G; } 161031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu const ExplodedGraph& getGraph() const { return G; } 16250a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 1630b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks /// \brief Run the analyzer's garbage collection - remove dead symbols and 16484c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// bindings from the state. 1650b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks /// 16684c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// Checkers can participate in this process with two callbacks: 16784c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation 16884c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// class for more information. 16984c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// 17084c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// \param Node The predecessor node, from which the processing should start. 17184c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// \param Out The returned set of output nodes. 17284c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// \param ReferenceStmt The statement which is about to be processed. 17384c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// Everything needed for this statement should be considered live. 17484c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// A null statement means that everything in child LocationContexts 17584c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// is dead. 17684c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// \param LC The location context of the \p ReferenceStmt. A null location 17784c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// context means that we have reached the end of analysis and that 17884c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// all statements and local variables should be considered dead. 17984c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// \param DiagnosticStmt Used as a location for any warnings that should 18084c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// occur while removing the dead (e.g. leaks). By default, the 18184c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// \p ReferenceStmt is used. 18284c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// \param K Denotes whether this is a pre- or post-statement purge. This 18384c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an 18484c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// entire location context is being cleared, in which case the 18584c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise, 18684c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default) 18784c484545c5906ba55143e212b4a5275ab55889fJordan Rose /// and \p ReferenceStmt must be valid (non-null). 1880b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, 18984c484545c5906ba55143e212b4a5275ab55889fJordan Rose const Stmt *ReferenceStmt, const LocationContext *LC, 19084c484545c5906ba55143e212b4a5275ab55889fJordan Rose const Stmt *DiagnosticStmt = 0, 1910b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind); 1920b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 193e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek /// processCFGElement - Called by CoreEngine. Used to generate new successor 1949c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu /// nodes by processing the 'effects' of a CFG element. 195ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks void processCFGElement(const CFGElement E, ExplodedNode *Pred, 196ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks unsigned StmtIdx, NodeBuilderContext *Ctx); 1979c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 198ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks void ProcessStmt(const CFGStmt S, ExplodedNode *Pred); 1999c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 200ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred); 2019c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 202ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred); 2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2044ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, 205056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, ExplodedNodeSet &Dst); 20636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose void ProcessDeleteDtor(const CFGDeleteDtor D, 20736d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose ExplodedNode *Pred, ExplodedNodeSet &Dst); 208056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks void ProcessBaseDtor(const CFGBaseDtor D, 209056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, ExplodedNodeSet &Dst); 210056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks void ProcessMemberDtor(const CFGMemberDtor D, 211056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, ExplodedNodeSet &Dst); 2124ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu void ProcessTemporaryDtor(const CFGTemporaryDtor D, 213056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, ExplodedNodeSet &Dst); 2144ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 21527c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek /// Called by CoreEngine when processing the entrance of a CFGBlock. 216253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks virtual void processCFGBlockEntrance(const BlockEdge &L, 217b355be838a22a511d078504b2277f70aea52ca85Anna Zaks NodeBuilderWithSinks &nodeBuilder, 218b355be838a22a511d078504b2277f70aea52ca85Anna Zaks ExplodedNode *Pred); 21927c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek 220d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis /// ProcessBranch - Called by CoreEngine. Used to generate successor 221b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// nodes by processing the 'effects' of a branch condition. 2229c378f705405d37f49795d5e915989de774fe11fTed Kremenek void processBranch(const Stmt *Condition, const Stmt *Term, 223a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks NodeBuilderContext& BuilderCtx, 224ad62deeb70e97da6bd514dd390ea1ce6af6ad81dAnna Zaks ExplodedNode *Pred, 2251aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks ExplodedNodeSet &Dst, 226a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks const CFGBlock *DstT, 227a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks const CFGBlock *DstF); 2281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2290f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek /// Called by CoreEngine. Used to processing branching behavior 2300f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek /// at static initalizers. 2310f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek void processStaticInitializer(const DeclStmt *DS, 2320f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek NodeBuilderContext& BuilderCtx, 2330f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek ExplodedNode *Pred, 2340f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek ExplodedNodeSet &Dst, 2350f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek const CFGBlock *DstT, 2360f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek const CFGBlock *DstF); 2370f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek 238e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek /// processIndirectGoto - Called by CoreEngine. Used to generate successor 239b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// nodes by processing the 'effects' of a computed goto jump. 240e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek void processIndirectGoto(IndirectGotoNodeBuilder& builder); 2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 242d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis /// ProcessSwitch - Called by CoreEngine. Used to generate successor 243b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// nodes by processing the 'effects' of a switch statement. 244e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek void processSwitch(SwitchNodeBuilder& builder); 2451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 246344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks /// Called by CoreEngine. Used to generate end-of-path 247344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks /// nodes when the control reaches the end of a function. 248b355be838a22a511d078504b2277f70aea52ca85Anna Zaks void processEndOfFunction(NodeBuilderContext& BC, 249b355be838a22a511d078504b2277f70aea52ca85Anna Zaks ExplodedNode *Pred); 250102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 2518501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks /// Remove dead bindings/symbols before exiting a function. 2528501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks void removeDeadOnEndOfFunction(NodeBuilderContext& BC, 2538501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks ExplodedNode *Pred, 2548501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks ExplodedNodeSet &Dst); 2558501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks 256ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek /// Generate the entry node of the callee. 2573070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek void processCallEnter(CallEnter CE, ExplodedNode *Pred); 258102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 2590b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks /// Generate the sequence of nodes that simulate the call exit and the post 2600b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks /// visit for CallExpr. 261894212e9510299abb203801e014fec76b7926a05Ted Kremenek void processCallExit(ExplodedNode *Pred); 262102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 263d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis /// Called by CoreEngine when the analysis worklist has terminated. 264e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek void processEndWorklist(bool hasWorkRemaining); 265ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek 2669c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek /// evalAssume - Callback function invoked by the ConstraintManager when 26732a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek /// making assumptions about state values. 2688bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef processAssume(ProgramStateRef state, SVal cond,bool assumption); 2691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a 271e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek /// region change should trigger a processRegionChanges update. 2728bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek bool wantsRegionChangeUpdate(ProgramStateRef state); 273c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose 27418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek /// processRegionChanges - Called by ProgramStateManager whenever a change is made 275c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose /// to the store. Used to update checkers that track region values. 2768bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef 2778bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek processRegionChanges(ProgramStateRef state, 278bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks const InvalidatedSymbols *invalidated, 279537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose ArrayRef<const MemRegion *> ExplicitRegions, 28066c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks ArrayRef<const MemRegion *> Regions, 281740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const CallEvent *Call); 282c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose 283dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose /// printState - Called by ProgramStateManager to print checker-specific data. 2848bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek void printState(raw_ostream &Out, ProgramStateRef State, 285dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose const char *NL, const char *Sep); 286dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose 28718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek virtual ProgramStateManager& getStateManager() { return StateMgr; } 28890e72e4106a0c3efa7575e9f9cba0c775bb54552Zhongxing Xu 28990e72e4106a0c3efa7575e9f9cba0c775bb54552Zhongxing Xu StoreManager& getStoreManager() { return StateMgr.getStoreManager(); } 2901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 291a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek ConstraintManager& getConstraintManager() { 292a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek return StateMgr.getConstraintManager(); 293a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek } 2941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 295c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek // FIXME: Remove when we migrate over to just using SValBuilder. 2966297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek BasicValueFactory& getBasicVals() { 2976297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek return StateMgr.getBasicVals(); 2986297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek } 2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 300044b6f0417cb98741f277602fabf5f07ec9a02c0Ted Kremenek // FIXME: Remove when we migrate over to just using ValueManager. 30100a3a5f024ac54088ab887712b292171188064f0Ted Kremenek SymbolManager& getSymbolManager() { return SymMgr; } 30200a3a5f024ac54088ab887712b292171188064f0Ted Kremenek const SymbolManager& getSymbolManager() const { return SymMgr; } 3031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 304bc42c533e7d3d946704a49e242939dd232f33072Tom Care // Functions for external checking of whether we have unfinished work 305422ab7a49a9a4252dbc6350e49d7a5708337b9c7Ted Kremenek bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); } 306d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); } 307422ab7a49a9a4252dbc6350e49d7a5708337b9c7Ted Kremenek bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); } 308bc42c533e7d3d946704a49e242939dd232f33072Tom Care 309d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis const CoreEngine &getCoreEngine() const { return Engine; } 310bc42c533e7d3d946704a49e242939dd232f33072Tom Care 3111670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekpublic: 312b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// Visit - Transfer function logic for all statements. Dispatches to 313b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// other functions that handle specific kinds of statements. 3149c378f705405d37f49795d5e915989de774fe11fTed Kremenek void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst); 3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 316c5b1bf10133a8ecbfe9e6b3ec92bae84e3d927e8Ted Kremenek /// VisitArraySubscriptExpr - Transfer function for array accesses. 3179c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex, 3189c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, 3199c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst); 3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 321df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier /// VisitGCCAsmStmt - Transfer function logic for inline asm. 322df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, 323df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier ExplodedNodeSet &Dst); 3248cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier 3258cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier /// VisitMSAsmStmt - Transfer function logic for MS inline asm. 3268cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, 3278cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier ExplodedNodeSet &Dst); 328df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier 329c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek /// VisitBlockExpr - Transfer function logic for BlockExprs. 33003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 33103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu ExplodedNodeSet &Dst); 3321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 333b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// VisitBinaryOperator - Transfer function logic for binary operators. 3349c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, 3359c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst); 336469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek 3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 338de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek /// VisitCall - Transfer function for function calls. 3399c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, 3409c378f705405d37f49795d5e915989de774fe11fTed 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. 3479c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, 3489c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst); 3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 350892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs. 3519c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, 3529c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst); 35367d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek 354b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// VisitDeclStmt - Transfer function logic for DeclStmts. 3559c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, 3569c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst); 3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 358b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose 3599c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, 3609c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst); 36161dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek 3629c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, 3639c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst); 364c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu 365b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// VisitLogicalExpr - Transfer function logic for '&&', '||' 3669c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, 3679c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst); 3681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 369469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek /// VisitMemberExpr - Transfer function for member expressions. 3709c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, 3719c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst); 3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3734beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek /// Transfer function logic for ObjCAtSynchronizedStmts. 3744beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, 3754beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst); 3764beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek 377892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek /// Transfer function logic for computing the lvalue of an Objective-C ivar. 3789c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, 3799c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst); 380af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek 381af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek /// VisitObjCForCollectionStmt - Transfer function logic for 382af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek /// ObjCForCollectionStmt. 3839c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, 3849c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst); 3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 386d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, 3879c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst); 3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 38902737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek /// VisitReturnStmt - Transfer function logic for return statements. 3909c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, 3919c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst); 3928ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 3938ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor /// VisitOffsetOfExpr - Transfer function for offsetof. 3949c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, 3959c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst); 3961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 397f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof. 3989c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, 3999c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst); 4001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 401b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek /// VisitUnaryOperator - Transfer function logic for unary operators. 4029c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, 4039c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst); 404bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu 4058ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks /// Handle ++ and -- (both pre- and post-increment). 4068ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks void VisitIncrementDecrementOperator(const UnaryOperator* U, 4078ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks ExplodedNode *Pred, 4088ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks ExplodedNodeSet &Dst); 409337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 410337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, 411337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek ExplodedNodeSet &Dst); 4128ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks 41303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 414bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu ExplodedNodeSet & Dst); 415d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu 416888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, 417888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ExplodedNodeSet &Dst); 418950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu 419200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, 420200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose const Stmt *S, bool IsBaseDtor, 421b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu ExplodedNode *Pred, ExplodedNodeSet &Dst); 422b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 42303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 424856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu ExplodedNodeSet &Dst); 425856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu 42603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, 4276b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu ExplodedNodeSet &Dst); 4286b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu 429bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu /// Create a C++ temporary object for an rvalue. 430eea72a925f294225391ecec876a342771c09b635Ted Kremenek void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 431eea72a925f294225391ecec876a342771c09b635Ted Kremenek ExplodedNode *Pred, 432bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu ExplodedNodeSet &Dst); 433b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek 4340caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic 43548af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) 43648af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek /// with those assumptions. 4370caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 43803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const Expr *Ex); 4396c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek 4406c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek std::pair<const ProgramPointTag *, const ProgramPointTag*> 4410caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek geteagerlyAssumeBinOpBifurcationTags(); 4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4439c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal evalMinus(SVal X) { 4445251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X; 445b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek } 4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4479c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal evalComplement(SVal X) { 4485251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X; 44990e420321f60860f4c4e7a68ca9f7567824b46ecTed Kremenek } 450248072a8b9cd956c4ac63172fc2af09790f7c6a9Zhongxing Xu 4511670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekpublic: 4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4538bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 454cd8f6ac9b613e1fe962ebf9c87d822ce765275e6Ted Kremenek NonLoc L, NonLoc R, QualType T) { 4559c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek return svalBuilder.evalBinOpNN(state, op, L, R, T); 4566297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek } 45710c16657eec144def180ee53d1e0249c9ed2b3b5Ted Kremenek 4588bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, 459cd8f6ac9b613e1fe962ebf9c87d822ce765275e6Ted Kremenek NonLoc L, SVal R, QualType T) { 4605251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L, 4615251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie R.castAs<NonLoc>(), T) : R; 462b640b3b5dfccaf259967cb2cb6755c9aa20d4423Ted Kremenek } 4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4648bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, 465ff4264dae31cf42807b64ecc114906b0b835690aTed Kremenek SVal LHS, SVal RHS, QualType T) { 4669c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T); 467ff4264dae31cf42807b64ecc114906b0b835690aTed Kremenek } 4685b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek 4691670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekprotected: 4709c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek /// evalBind - Handle the semantics of binding a value to a specific location. 4719c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek /// This method is used by evalStore, VisitDeclStmt, and others. 4729c378f705405d37f49795d5e915989de774fe11fTed Kremenek void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, 4733682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose SVal location, SVal Val, bool atDeclInit = false, 4743682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose const ProgramPoint *PP = 0); 4751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4761655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks /// Call PointerEscape callback when a value escapes as a result of bind. 477bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, 478bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks SVal Loc, SVal Val); 4791655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks /// Call PointerEscape callback when a value escapes as a result of 4801655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks /// region invalidation. 481da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev /// \param[in] ITraits Specifies invalidation traits for regions/symbols. 48241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks ProgramStateRef notifyCheckersOfPointerEscape( 483bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks ProgramStateRef State, 484bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks const InvalidatedSymbols *Invalidated, 485bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks ArrayRef<const MemRegion *> ExplicitRegions, 486bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks ArrayRef<const MemRegion *> Regions, 48741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks const CallEvent *Call, 488da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev RegionAndSymbolInvalidationTraits &ITraits); 489bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 4901670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekpublic: 491b4b817d704287836b52b34369009e682f208aa2bTed Kremenek // FIXME: 'tag' should be removed, and a LocationContext should be used 492b4b817d704287836b52b34369009e682f208aa2bTed Kremenek // instead. 493834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan // FIXME: Comment on the meaning of the arguments, when 'St' may not 494834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan // be the same as Pred->state, and when 'location' may not be the 495834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan // same as state->getLValue(Ex). 496834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan /// Simulate a read of the result of Ex. 497bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek void evalLoad(ExplodedNodeSet &Dst, 498bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *NodeEx, /* Eventually will be a CFGStmt */ 499bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *BoundExpr, 500bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 501bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ProgramStateRef St, 502bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek SVal location, 503bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const ProgramPointTag *tag = 0, 504652be346f74feba027bcbdeb6a3e3f4755a0e62cZhongxing Xu QualType LoadTy = QualType()); 5051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 506b4b817d704287836b52b34369009e682f208aa2bTed Kremenek // FIXME: 'tag' should be removed, and a LocationContext should be used 507b4b817d704287836b52b34369009e682f208aa2bTed Kremenek // instead. 5089c378f705405d37f49795d5e915989de774fe11fTed Kremenek void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, 5098bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, 510ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0); 51169f87c956b3ac2b80124fd9604af012e1061473aJordan Rose 512e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks /// \brief Create a new state in which the call return value is binded to the 513e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks /// call origin expression. 514e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks ProgramStateRef bindReturnValue(const CallEvent &Call, 515e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks const LocationContext *LCtx, 516e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks ProgramStateRef State); 517e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks 518645baeed6800f952e9ad1d5666e01080385531a2Jordan Rose /// Evaluate a call, running pre- and post-call checks and allowing checkers 519645baeed6800f952e9ad1d5666e01080385531a2Jordan Rose /// to be responsible for handling the evaluation of the call itself. 52069f87c956b3ac2b80124fd9604af012e1061473aJordan Rose void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, 521645baeed6800f952e9ad1d5666e01080385531a2Jordan Rose const CallEvent &Call); 522e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks 5239dc5167e4017ef4c8b327abb6f72225eec2e0f19Anna Zaks /// \brief Default implementation of call evaluation. 524e81ce256b62717dd846bd19aecc4115a0dcd4995Anna Zaks void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, 52569f87c956b3ac2b80124fd9604af012e1061473aJordan Rose const CallEvent &Call); 526834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wanprivate: 527bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek void evalLoadCommon(ExplodedNodeSet &Dst, 528bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *NodeEx, /* Eventually will be a CFGStmt */ 529bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *BoundEx, 530bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 531bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ProgramStateRef St, 532bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek SVal location, 533bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const ProgramPointTag *tag, 534852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek QualType LoadTy); 535852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 536852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // FIXME: 'tag' should be removed, and a LocationContext should be used 537852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // instead. 538bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek void evalLocation(ExplodedNodeSet &Dst, 539bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Stmt *NodeEx, /* This will eventually be a CFGStmt */ 540bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Stmt *BoundEx, 541bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 5428bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef St, SVal location, 543ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag, bool isLoad); 5441c625f25055331bf76ab5479a8060d2b0f61e8b8Zhongxing Xu 5454ea9b89ff6dc50d5404eb56cad5e5870bce49ef2Anna Zaks /// Count the stack depth and determine if the call is recursive. 5464ea9b89ff6dc50d5404eb56cad5e5870bce49ef2Anna Zaks void examineStackFrames(const Decl *D, const LocationContext *LCtx, 5474ea9b89ff6dc50d5404eb56cad5e5870bce49ef2Anna Zaks bool &IsRecursive, unsigned &StackDepth); 5484ea9b89ff6dc50d5404eb56cad5e5870bce49ef2Anna Zaks 5498dadf15224f1a8df96793e5fc4e0b0e38a5ffbe4Anna Zaks /// Checks our policies and decides weither the given call should be inlined. 5508dadf15224f1a8df96793e5fc4e0b0e38a5ffbe4Anna Zaks bool shouldInlineCall(const CallEvent &Call, const Decl *D, 5518dadf15224f1a8df96793e5fc4e0b0e38a5ffbe4Anna Zaks const ExplodedNode *Pred); 5528dadf15224f1a8df96793e5fc4e0b0e38a5ffbe4Anna Zaks 553e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, 554e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks ExplodedNode *Pred, ProgramStateRef State); 555e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks 556e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks /// \brief Conservatively evaluate call by invalidating regions and binding 557e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks /// a conjured return value. 558e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr, 559e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks ExplodedNode *Pred, ProgramStateRef State); 560e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks 561e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks /// \brief Either inline or process the call conservatively (or both), based 562e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks /// on DynamicDispatchBifurcation data. 563e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks void BifurcateCall(const MemRegion *BifurReg, 564e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, 565e90d3f847dcce76237078b67db8895eb7a24189eAnna Zaks ExplodedNode *Pred); 5665903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 5675903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC); 568bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose 569a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose /// Models a trivial copy or move constructor or trivial assignment operator 570a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose /// call with a simple bind. 571bc403861bc4e6f7ad1371e9e129f0f25b38b3a9aJordan Rose void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred, 572a8d937e4bdd39cdf503f77454e9dc4c9c730a9f7Jordan Rose const CallEvent &Call); 5735e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose 5745e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose /// If the value of the given expression is a NonLoc, copy it into a new 5755e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose /// temporary object region, and replace the value of the expression with 5765e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose /// that. 5775e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose /// 5785e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose /// If \p ResultE is provided, the new region will be bound to this expression 5795e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose /// instead of \p E. 5805e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State, 5815e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const LocationContext *LC, 5825e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const Expr *E, 5835e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const Expr *ResultE = 0); 5845903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks}; 5855903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 5865903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks/// Traits for storing the call processing policy inside GDM. 5875903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks/// The GDM stores the corresponding CallExpr pointer. 588466224fd068a0a0084968a7f521a690a51c3b226Jordan Rose// FIXME: This does not use the nice trait macros because it must be accessible 589466224fd068a0a0084968a7f521a690a51c3b226Jordan Rose// from multiple translation units. 5905903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaksstruct ReplayWithoutInlining{}; 5915903a373db3d27794c90b25687e0dd6adb0e497dAnna Zakstemplate <> 5925903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaksstruct ProgramStateTrait<ReplayWithoutInlining> : 593bdc691f1d61765dd806d5ae3b75ae004f676a7c9Jordan Rose public ProgramStatePartialTrait<const void*> { 5945903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks static void *GDMIndex() { static int index = 0; return &index; } 595b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek}; 5961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 59765423aeb996a296cf2964f136ce4a4a937bd1687Zhongxing Xu} // end ento namespace 5985a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 599c0c3f5dbc9e78aa53a86c7d5e3eeda23ddad93d6Ted Kremenek} // end clang namespace 600c0c3f5dbc9e78aa53a86c7d5e3eeda23ddad93d6Ted Kremenek 601d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek#endif 602