Consumed.h revision 039970aae2b7e59ac4de5f147dfbc3c91b275b9e
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
123  class ConsumedBlockInfo {
124
125    ConsumedStateMap **StateMapsArray;
126    PostOrderCFGView::CFGBlockSet VisitedBlocks;
127
128  public:
129
130    ConsumedBlockInfo() : StateMapsArray(NULL) {}
131
132    ConsumedBlockInfo(const CFG *CFGraph)
133      : StateMapsArray(new ConsumedStateMap*[CFGraph->getNumBlockIDs()]()),
134        VisitedBlocks(CFGraph) {}
135
136    void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap,
137                 bool &AlreadyOwned);
138    void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap);
139
140    ConsumedStateMap* getInfo(const CFGBlock *Block);
141
142    void markVisited(const CFGBlock *Block);
143  };
144
145  struct VarTestResult {
146    const VarDecl *Var;
147    SourceLocation Loc;
148    bool UnconsumedInTrueBranch;
149
150    VarTestResult() : Var(NULL), Loc(), UnconsumedInTrueBranch(true) {}
151
152    VarTestResult(const VarDecl *Var, SourceLocation Loc,
153                  bool UnconsumedInTrueBranch)
154      : Var(Var), Loc(Loc), UnconsumedInTrueBranch(UnconsumedInTrueBranch) {}
155  };
156
157  /// A class that handles the analysis of uniqueness violations.
158  class ConsumedAnalyzer {
159
160    typedef llvm::DenseMap<const CXXRecordDecl *, bool> CacheMapType;
161    typedef std::pair<const CXXRecordDecl *, bool> CachePairType;
162
163    ConsumedBlockInfo BlockInfo;
164    ConsumedStateMap *CurrStates;
165
166    CacheMapType ConsumableTypeCache;
167
168    bool hasConsumableAttributes(const CXXRecordDecl *RD);
169    void splitState(const CFGBlock *CurrBlock, const IfStmt *Terminator);
170
171  public:
172
173    ConsumedWarningsHandlerBase &WarningsHandler;
174
175    ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler)
176        : WarningsHandler(WarningsHandler) {}
177
178    /// \brief Check to see if the type is a consumable type.
179    bool isConsumableType(QualType Type);
180
181    /// \brief Check a function's CFG for consumed violations.
182    ///
183    /// We traverse the blocks in the CFG, keeping track of the state of each
184    /// value who's type has uniquness annotations.  If methods are invoked in
185    /// the wrong state a warning is issued.  Each block in the CFG is traversed
186    /// exactly once.
187    void run(AnalysisDeclContext &AC);
188  };
189
190  /// \brief Check to see if a function tests an object's validity.
191  bool isTestingFunction(const CXXMethodDecl *MethodDecl);
192
193}} // end namespace clang::consumed
194
195#endif
196