Consumed.h revision 5fdd207ec8f4c1f58bd74f8a84ce1935487563ce
1//===- Consumed.h ----------------------------------------------*- C++ --*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// A intra-procedural analysis for checking consumed properties.  This is based,
11// in part, on research on linear types.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_CONSUMED_H
16#define LLVM_CLANG_CONSUMED_H
17
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/ExprCXX.h"
20#include "clang/AST/StmtCXX.h"
21#include "clang/Analysis/AnalysisContext.h"
22#include "clang/Analysis/Analyses/PostOrderCFGView.h"
23#include "clang/Basic/SourceLocation.h"
24
25namespace clang {
26namespace consumed {
27
28  typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes;
29  typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;
30  typedef std::list<DelayedDiag> DiagList;
31
32  class ConsumedWarningsHandlerBase {
33
34  public:
35
36    virtual ~ConsumedWarningsHandlerBase();
37
38    /// \brief Emit the warnings and notes left by the analysis.
39    virtual void emitDiagnostics() {}
40
41    /// Warn about unnecessary-test errors.
42    /// \param VariableName -- The name of the variable that holds the unique
43    /// value.
44    ///
45    /// \param Loc -- The SourceLocation of the unnecessary test.
46    virtual void warnUnnecessaryTest(StringRef VariableName,
47                                     StringRef VariableState,
48                                     SourceLocation Loc) {}
49
50    /// Warn about use-while-consumed errors.
51    /// \param MethodName -- The name of the method that was incorrectly
52    /// invoked.
53    ///
54    /// \param Loc -- The SourceLocation of the method invocation.
55    virtual void warnUseOfTempWhileConsumed(StringRef MethodName,
56                                            SourceLocation Loc) {}
57
58    /// Warn about use-in-unknown-state errors.
59    /// \param MethodName -- The name of the method that was incorrectly
60    /// invoked.
61    ///
62    /// \param Loc -- The SourceLocation of the method invocation.
63    virtual void warnUseOfTempInUnknownState(StringRef MethodName,
64                                             SourceLocation Loc) {}
65
66    /// Warn about use-while-consumed errors.
67    /// \param MethodName -- The name of the method that was incorrectly
68    /// invoked.
69    ///
70    /// \param VariableName -- The name of the variable that holds the unique
71    /// value.
72    ///
73    /// \param Loc -- The SourceLocation of the method invocation.
74    virtual void warnUseWhileConsumed(StringRef MethodName,
75                                      StringRef VariableName,
76                                      SourceLocation Loc) {}
77
78    /// Warn about use-in-unknown-state errors.
79    /// \param MethodName -- The name of the method that was incorrectly
80    /// invoked.
81    ///
82    /// \param VariableName -- The name of the variable that holds the unique
83    /// value.
84    ///
85    /// \param Loc -- The SourceLocation of the method invocation.
86    virtual void warnUseInUnknownState(StringRef MethodName,
87                                       StringRef VariableName,
88                                       SourceLocation Loc) {}
89  };
90
91  enum ConsumedState {
92    // No state information for the given variable.
93    CS_None,
94
95    CS_Unknown,
96    CS_Unconsumed,
97    CS_Consumed
98  };
99
100  class ConsumedStateMap {
101
102    typedef llvm::DenseMap<const VarDecl *, ConsumedState> MapType;
103    typedef std::pair<const VarDecl *, ConsumedState> PairType;
104
105  protected:
106
107    MapType Map;
108
109  public:
110    /// \brief Get the consumed state of a given variable.
111    ConsumedState getState(const VarDecl *Var);
112
113    /// \brief Merge this state map with another map.
114    void intersect(const ConsumedStateMap *Other);
115
116    /// \brief Mark all variables as unknown.
117    void makeUnknown();
118
119    /// \brief Set the consumed state of a given variable.
120    void setState(const VarDecl *Var, ConsumedState State);
121
122    /// \brief Remove the variable from our state map.
123    void remove(const VarDecl *Var);
124  };
125
126  class ConsumedBlockInfo {
127
128    ConsumedStateMap **StateMapsArray;
129    PostOrderCFGView::CFGBlockSet VisitedBlocks;
130
131  public:
132
133    ConsumedBlockInfo() : StateMapsArray(NULL) {}
134
135    ConsumedBlockInfo(const CFG *CFGraph)
136      : StateMapsArray(new ConsumedStateMap*[CFGraph->getNumBlockIDs()]()),
137        VisitedBlocks(CFGraph) {}
138
139    void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap,
140                 bool &AlreadyOwned);
141    void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap);
142
143    ConsumedStateMap* getInfo(const CFGBlock *Block);
144
145    void markVisited(const CFGBlock *Block);
146  };
147
148  struct VarTestResult {
149    const VarDecl *Var;
150    SourceLocation Loc;
151    bool UnconsumedInTrueBranch;
152
153    VarTestResult() : Var(NULL), Loc(), UnconsumedInTrueBranch(true) {}
154
155    VarTestResult(const VarDecl *Var, SourceLocation Loc,
156                  bool UnconsumedInTrueBranch)
157      : Var(Var), Loc(Loc), UnconsumedInTrueBranch(UnconsumedInTrueBranch) {}
158  };
159
160  /// A class that handles the analysis of uniqueness violations.
161  class ConsumedAnalyzer {
162
163    typedef llvm::DenseMap<const CXXRecordDecl *, bool> CacheMapType;
164    typedef std::pair<const CXXRecordDecl *, bool> CachePairType;
165
166    ConsumedBlockInfo BlockInfo;
167    ConsumedStateMap *CurrStates;
168
169    CacheMapType ConsumableTypeCache;
170
171    bool hasConsumableAttributes(const CXXRecordDecl *RD);
172    void splitState(const CFGBlock *CurrBlock, const IfStmt *Terminator);
173
174  public:
175
176    ConsumedWarningsHandlerBase &WarningsHandler;
177
178    ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler)
179        : WarningsHandler(WarningsHandler) {}
180
181    /// \brief Check to see if the type is a consumable type.
182    bool isConsumableType(QualType Type);
183
184    /// \brief Check a function's CFG for consumed violations.
185    ///
186    /// We traverse the blocks in the CFG, keeping track of the state of each
187    /// value who's type has uniquness annotations.  If methods are invoked in
188    /// the wrong state a warning is issued.  Each block in the CFG is traversed
189    /// exactly once.
190    void run(AnalysisDeclContext &AC);
191  };
192}} // end namespace clang::consumed
193
194#endif
195