1df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===- Consumed.h ----------------------------------------------*- C++ --*-===// 2df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// 3df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// The LLVM Compiler Infrastructure 4df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// 5df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// This file is distributed under the University of Illinois Open Source 6df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// License. See LICENSE.TXT for details. 7df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// 8df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===// 9df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// 10df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// A intra-procedural analysis for checking consumed properties. This is based, 11df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// in part, on research on linear types. 12df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins// 13df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins//===----------------------------------------------------------------------===// 14df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 15df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins#ifndef LLVM_CLANG_CONSUMED_H 16df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins#define LLVM_CLANG_CONSUMED_H 17df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 18df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins#include "clang/AST/DeclCXX.h" 19df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins#include "clang/AST/ExprCXX.h" 20df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins#include "clang/AST/StmtCXX.h" 21df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins#include "clang/Analysis/Analyses/PostOrderCFGView.h" 22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Analysis/AnalysisContext.h" 23df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins#include "clang/Basic/SourceLocation.h" 24df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 25df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace clang { 26df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchinsnamespace consumed { 27b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins 2866540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins enum ConsumedState { 2966540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins // No state information for the given variable. 3066540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins CS_None, 3166540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins 3266540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins CS_Unknown, 3366540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins CS_Unconsumed, 3466540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins CS_Consumed 3566540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins }; 3666540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins 37b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins class ConsumedStmtVisitor; 38b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins 392d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes; 402d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag; 412d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner typedef std::list<DelayedDiag> DiagList; 422d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner 432d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner class ConsumedWarningsHandlerBase { 442d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner 452d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner public: 462d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner 472d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner virtual ~ConsumedWarningsHandlerBase(); 482d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner 492d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// \brief Emit the warnings and notes left by the analysis. 502d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner virtual void emitDiagnostics() {} 510e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins 527385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins /// \brief Warn that a variable's state doesn't match at the entry and exit 537385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins /// of a loop. 547385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins /// 557385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins /// \param Loc -- The location of the end of the loop. 567385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins /// 577385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins /// \param VariableName -- The name of the variable that has a mismatched 587385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins /// state. 597385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins virtual void warnLoopStateMismatch(SourceLocation Loc, 607385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins StringRef VariableName) {} 617385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins 62cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// \brief Warn about parameter typestate mismatches upon return. 63cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// 64cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// \param Loc -- The SourceLocation of the return statement. 65cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// 66cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// \param ExpectedState -- The state the return value was expected to be 67cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// in. 68cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// 69cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// \param ObservedState -- The state the return value was observed to be 70cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// in. 71cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins virtual void warnParamReturnTypestateMismatch(SourceLocation Loc, 72cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins StringRef VariableName, 73cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins StringRef ExpectedState, 74cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins StringRef ObservedState) {}; 75cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins 76d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins // FIXME: Add documentation. 77d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins virtual void warnParamTypestateMismatch(SourceLocation LOC, 78d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins StringRef ExpectedState, 79d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins StringRef ObservedState) {} 80d4f0e1991f42c69111213699fb2d09dedee1cd36DeLesley Hutchins 810e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins // FIXME: This can be removed when the attr propagation fix for templated 820e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins // classes lands. 830e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins /// \brief Warn about return typestates set for unconsumable types. 840e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins /// 850e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins /// \param Loc -- The location of the attributes. 860e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins /// 870e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins /// \param TypeName -- The name of the unconsumable type. 880e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins virtual void warnReturnTypestateForUnconsumableType(SourceLocation Loc, 890e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins StringRef TypeName) {} 900e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins 910e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins /// \brief Warn about return typestate mismatches. 92cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// 930e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins /// \param Loc -- The SourceLocation of the return statement. 94cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// 95cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// \param ExpectedState -- The state the return value was expected to be 96cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// in. 97cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// 98cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// \param ObservedState -- The state the return value was observed to be 99cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// in. 1000e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins virtual void warnReturnTypestateMismatch(SourceLocation Loc, 1010e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins StringRef ExpectedState, 1020e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins StringRef ObservedState) {} 1032d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner 104b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins /// \brief Warn about use-while-consumed errors. 1052d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// \param MethodName -- The name of the method that was incorrectly 1062d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// invoked. 1072d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// 10866540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins /// \param State -- The state the object was used in. 1092d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// 1102d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// \param Loc -- The SourceLocation of the method invocation. 11166540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins virtual void warnUseOfTempInInvalidState(StringRef MethodName, 11266540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins StringRef State, 1132d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner SourceLocation Loc) {} 1142d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner 115b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins /// \brief Warn about use-while-consumed errors. 1162d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// \param MethodName -- The name of the method that was incorrectly 1172d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// invoked. 1182d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// 11966540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins /// \param State -- The state the object was used in. 1202d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// 1212d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// \param VariableName -- The name of the variable that holds the unique 1222d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// value. 1232d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// 1242d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner /// \param Loc -- The SourceLocation of the method invocation. 12566540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins virtual void warnUseInInvalidState(StringRef MethodName, 1262d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner StringRef VariableName, 12766540857c08de7f1be9bea48381548d3942cf9d1DeLesley Hutchins StringRef State, 1282d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner SourceLocation Loc) {} 1292d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner }; 1302d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner 131df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins class ConsumedStateMap { 132df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1334c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins typedef llvm::DenseMap<const VarDecl *, ConsumedState> VarMapType; 1344c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins typedef llvm::DenseMap<const CXXBindTemporaryExpr *, ConsumedState> 1354c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins TmpMapType; 136df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 137df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins protected: 138df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 139b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins bool Reachable; 140b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins const Stmt *From; 1414c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins VarMapType VarMap; 1424c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins TmpMapType TmpMap; 143df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 144df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins public: 1456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ConsumedStateMap() : Reachable(true), From(nullptr) {} 146b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins ConsumedStateMap(const ConsumedStateMap &Other) 1474c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap), 1484c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins TmpMap() {} 149b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins 150cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// \brief Warn if any of the parameters being tracked are not in the state 151cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins /// they were declared to be in upon return from a function. 152cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins void checkParamsForReturnTypestate(SourceLocation BlameLoc, 153cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins ConsumedWarningsHandlerBase &WarningsHandler) const; 154cd0f6d7600a691ad81dab308e9905fb0cce1df4dDeLesley Hutchins 1554c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins /// \brief Clear the TmpMap. 1564c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins void clearTemporaries(); 1574c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins 158df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins /// \brief Get the consumed state of a given variable. 1597385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins ConsumedState getState(const VarDecl *Var) const; 160df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1614c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins /// \brief Get the consumed state of a given temporary value. 1624c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins ConsumedState getState(const CXXBindTemporaryExpr *Tmp) const; 1634c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins 164df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins /// \brief Merge this state map with another map. 165df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins void intersect(const ConsumedStateMap *Other); 166df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 1677385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins void intersectAtLoopHead(const CFGBlock *LoopHead, const CFGBlock *LoopBack, 1687385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins const ConsumedStateMap *LoopBackStates, 1697385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins ConsumedWarningsHandlerBase &WarningsHandler); 1707385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins 171b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins /// \brief Return true if this block is reachable. 172b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins bool isReachable() const { return Reachable; } 173b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins 174b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins /// \brief Mark the block as unreachable. 175b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins void markUnreachable(); 176b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins 177b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins /// \brief Set the source for a decision about the branching of states. 178b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins /// \param Source -- The statement that was the origin of a branching 179b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins /// decision. 180b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins void setSource(const Stmt *Source) { this->From = Source; } 181b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins 182df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins /// \brief Set the consumed state of a given variable. 183df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins void setState(const VarDecl *Var, ConsumedState State); 1845fdd207ec8f4c1f58bd74f8a84ce1935487563ceDeLesley Hutchins 1854c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins /// \brief Set the consumed state of a given temporary value. 1864c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins void setState(const CXXBindTemporaryExpr *Tmp, ConsumedState State); 1874c3e0bc7850df76824138ecfcc434388e7f69559DeLesley Hutchins 1886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// \brief Remove the temporary value from our state map. 1896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void remove(const CXXBindTemporaryExpr *Tmp); 1907385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins 1917385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins /// \brief Tests to see if there is a mismatch in the states stored in two 1927385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins /// maps. 1937385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins /// 1947385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins /// \param Other -- The second map to compare against. 1957385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins bool operator!=(const ConsumedStateMap *Other) const; 196df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins }; 197df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 198df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins class ConsumedBlockInfo { 1997385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins std::vector<ConsumedStateMap*> StateMapsArray; 20053fe3f55887cddc777d0aff09143483c6b29baa0DeLesley Hutchins std::vector<unsigned int> VisitOrder; 201df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 202df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins public: 20353fe3f55887cddc777d0aff09143483c6b29baa0DeLesley Hutchins ConsumedBlockInfo() { } 2046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ~ConsumedBlockInfo() { llvm::DeleteContainerPointers(StateMapsArray); } 2056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2067385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph) 2076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : StateMapsArray(NumBlocks, nullptr), VisitOrder(NumBlocks, 0) { 2087385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins unsigned int VisitOrderCounter = 0; 2097385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins for (PostOrderCFGView::iterator BI = SortedGraph->begin(), 2107385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins BE = SortedGraph->end(); BI != BE; ++BI) { 2117385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins VisitOrder[(*BI)->getBlockID()] = VisitOrderCounter++; 2127385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins } 2137385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins } 2147385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins 2157385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins bool allBackEdgesVisited(const CFGBlock *CurrBlock, 2167385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins const CFGBlock *TargetBlock); 217df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 218df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap, 219df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins bool &AlreadyOwned); 220df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap); 221df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 2227385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins ConsumedStateMap* borrowInfo(const CFGBlock *Block); 2237385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins 2247385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins void discardInfo(const CFGBlock *Block); 2257385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins 226df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins ConsumedStateMap* getInfo(const CFGBlock *Block); 227df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 2287385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins bool isBackEdge(const CFGBlock *From, const CFGBlock *To); 2297385840b600d0e4a96d75042f612f6430e4a0390DeLesley Hutchins bool isBackEdgeTarget(const CFGBlock *Block); 230df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins }; 231df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 232df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins /// A class that handles the analysis of uniqueness violations. 233df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins class ConsumedAnalyzer { 234df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 235df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins ConsumedBlockInfo BlockInfo; 236df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins ConsumedStateMap *CurrStates; 237df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 2380e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins ConsumedState ExpectedReturnState; 2390e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins 240a33ab6074a2cc60fe895d6669f9ee776c5fea335David Blaikie void determineExpectedReturnState(AnalysisDeclContext &AC, 241a33ab6074a2cc60fe895d6669f9ee776c5fea335David Blaikie const FunctionDecl *D); 242df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins bool hasConsumableAttributes(const CXXRecordDecl *RD); 243b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins bool splitState(const CFGBlock *CurrBlock, 244b7dc1f5f30e1e46e44389b036d48f9614cfd5fe3DeLesley Hutchins const ConsumedStmtVisitor &Visitor); 245df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 246df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins public: 247df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 248df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins ConsumedWarningsHandlerBase &WarningsHandler; 2492d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner 2502d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler) 2512d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner : WarningsHandler(WarningsHandler) {} 2522d84f6b563e39c1e90e4d3d7e6846d46bc58ff5dReid Kleckner 2530e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins ConsumedState getExpectedReturnState() const { return ExpectedReturnState; } 2540e8534efc3c536795ede0128aed86a6b8ad53ab7DeLesley Hutchins 255df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins /// \brief Check a function's CFG for consumed violations. 256df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins /// 257df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins /// We traverse the blocks in the CFG, keeping track of the state of each 258df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins /// value who's type has uniquness annotations. If methods are invoked in 259df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins /// the wrong state a warning is issued. Each block in the CFG is traversed 260df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins /// exactly once. 261df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins void run(AnalysisDeclContext &AC); 262df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins }; 263df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins}} // end namespace clang::consumed 264df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins 265df7bef07eebd5c7913e8be09c62a6a470f255fd2DeLesley Hutchins#endif 266