CheckerContext.h revision 3f5e8d87dbf449d8b39fe96068415428594d370e
16bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis//== CheckerContext.h - Context info for path-sensitive checkers--*- C++ -*--=// 26bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 36bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 46bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 56bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 66bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 76bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 86bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 96bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 106bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// This file defines CheckerContext that provides contextual info for 116bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// path-sensitive checkers. 126bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 136bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 146bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 156bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#ifndef LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT 166bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#define LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT 176bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 186bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#include "clang/Analysis/Support/SaveAndRestore.h" 196bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 206bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 216bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisnamespace clang { 226bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 236bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisnamespace ento { 246bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 256bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisclass CheckerContext { 266bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ExplodedNodeSet &Dst; 276bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis StmtNodeBuilder &B; 286bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ExprEngine &Eng; 296bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ExplodedNode *Pred; 306bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis SaveAndRestore<bool> OldSink; 316bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis SaveOr OldHasGen; 323f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks const ProgramPoint Location; 3318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek const ProgramState *ST; 346bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis const unsigned size; 356bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidispublic: 366bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis bool *respondsToCallback; 376bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidispublic: 3818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek CheckerContext(ExplodedNodeSet &dst, 3918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek StmtNodeBuilder &builder, 4018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ExprEngine &eng, 4118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ExplodedNode *pred, 423f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks const ProgramPoint &loc, 436bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis bool *respondsToCB = 0, 4418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek const ProgramState *st = 0) 4518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek : Dst(dst), 4618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek B(builder), 4718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek Eng(eng), 4818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek Pred(pred), 496bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis OldSink(B.BuildSinks), 506bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis OldHasGen(B.hasGeneratedNode), 513f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks Location(loc), 5218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ST(st), 5318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek size(Dst.size()), 546bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis respondsToCallback(respondsToCB) {} 556bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 566bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ~CheckerContext(); 576bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 586bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ExprEngine &getEngine() { 596bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng; 606bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 616bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 626bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis AnalysisManager &getAnalysisManager() { 636bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getAnalysisManager(); 646bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 656bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 666bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ConstraintManager &getConstraintManager() { 676bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getConstraintManager(); 686bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 696bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 706bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis StoreManager &getStoreManager() { 716bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getStoreManager(); 726bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 736bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 746bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ExplodedNodeSet &getNodeSet() { return Dst; } 756bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ExplodedNode *&getPredecessor() { return Pred; } 7618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek const ProgramState *getState() { return ST ? ST : Pred->getState(); } 776bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 785d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks /// \brief Returns the number of times the current block has been visited 795d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks /// along the analyzed path. 805d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks unsigned getCurrentBlockCount() {return B.getCurrentBlockCount();} 815d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks 826bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ASTContext &getASTContext() { 836bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getContext(); 846bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 856bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 866bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis BugReporter &getBugReporter() { 876bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getBugReporter(); 886bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 896bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 906bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis SourceManager &getSourceManager() { 916bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return getBugReporter().getSourceManager(); 926bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 936bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 946bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis SValBuilder &getSValBuilder() { 956bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Eng.getSValBuilder(); 966bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 976bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 983f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks SymbolManager &getSymbolManager() { 993f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks return getSValBuilder().getSymbolManager(); 1003f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks } 1013f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks 10217a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose bool isObjCGCEnabled() { 10317a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose return Eng.isObjCGCEnabled(); 10417a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose } 10517a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose 1068ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks /// \brief Generate a default checker node (containing checker tag but no 1078ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks /// checker state changes). 1086bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis ExplodedNode *generateNode(bool autoTransition = true) { 10950f3cade2a87bda005ae08d42b51c5b960b07779Anna Zaks return generateNode(getState(), autoTransition); 1106bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1116bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1128ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks /// \brief Generate a new checker node with the given predecessor. 1138ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks /// Allows checkers to generate a chain of nodes. 11418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ExplodedNode *generateNode(const ProgramState *state, 11518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ExplodedNode *pred, 116cbb7add8d7e3f868a6695a601e45fc13257bd9f5Anna Zaks const ProgramPointTag *tag = 0, 1176bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis bool autoTransition = true) { 118cbb7add8d7e3f868a6695a601e45fc13257bd9f5Anna Zaks ExplodedNode *N = generateNodeImpl(state, false, pred, tag); 1196bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis if (N && autoTransition) 1206bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis addTransition(N); 1216bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return N; 1226bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1236bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1248ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks /// \brief Generate a new checker node. 12518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ExplodedNode *generateNode(const ProgramState *state, 12618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek bool autoTransition = true, 127ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag = 0) { 12850f3cade2a87bda005ae08d42b51c5b960b07779Anna Zaks ExplodedNode *N = generateNodeImpl(state, false, 0, tag); 1296bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis if (N && autoTransition) 1306bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis addTransition(N); 1316bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return N; 1326bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1336bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1348ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks /// \brief Generate a sink node. Generating sink stops exploration of the 1358ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks /// given path. 13618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ExplodedNode *generateSink(const ProgramState *state = 0) { 13750f3cade2a87bda005ae08d42b51c5b960b07779Anna Zaks return generateNodeImpl(state ? state : getState(), true); 1386bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1396bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1406bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis void addTransition(ExplodedNode *node) { 1416bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis Dst.Add(node); 1426bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1436bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 14418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek void addTransition(const ProgramState *state, 14518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek const ProgramPointTag *tag = 0) { 1466bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis assert(state); 1476bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis // If the 'state' is not new, we need to check if the cached state 'ST' 1486bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis // is new. 1490e89061a399bae32f0eca5b85658ad66a58c504dAnna Zaks if (state != getState() || (ST && ST != Pred->getState())) 1506bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis // state is new or equals to ST. 1516bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis generateNode(state, true, tag); 1526bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis else 1536bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis Dst.Add(Pred); 1546bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1556bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1566bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis void EmitReport(BugReport *R) { 1576bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis Eng.getBugReporter().EmitReport(R); 1586bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1596bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1606bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis AnalysisContext *getCurrentAnalysisContext() const { 1616bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return Pred->getLocationContext()->getAnalysisContext(); 1626bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1636bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1646bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisprivate: 16550f3cade2a87bda005ae08d42b51c5b960b07779Anna Zaks ExplodedNode *generateNodeImpl(const ProgramState *state, 16618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek bool markAsSink, 16750f3cade2a87bda005ae08d42b51c5b960b07779Anna Zaks ExplodedNode *pred = 0, 16850f3cade2a87bda005ae08d42b51c5b960b07779Anna Zaks const ProgramPointTag *tag = 0) { 1693f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks 1703f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks ExplodedNode *node = B.generateNode(tag ? Location.withTag(tag) : Location, 1713f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks state, 1723f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks pred ? pred : Pred); 1736bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis if (markAsSink && node) 1746bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis node->markAsSink(); 1756bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis return node; 1766bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1776bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis}; 1786bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1796bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis} // end GR namespace 1806bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1816bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis} // end clang namespace 1826bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1836bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#endif 184