Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- Consumed.h -----------------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// A intra-procedural analysis for checking consumed properties.  This is based,
10
// in part, on research on linear types.
11
//
12
//===----------------------------------------------------------------------===//
13
 
14
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_CONSUMED_H
15
#define LLVM_CLANG_ANALYSIS_ANALYSES_CONSUMED_H
16
 
17
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
18
#include "clang/Analysis/CFG.h"
19
#include "clang/Basic/LLVM.h"
20
#include "clang/Basic/PartialDiagnostic.h"
21
#include "clang/Basic/SourceLocation.h"
22
#include "llvm/ADT/DenseMap.h"
23
#include "llvm/ADT/SmallVector.h"
24
#include "llvm/ADT/StringRef.h"
25
#include <list>
26
#include <memory>
27
#include <utility>
28
#include <vector>
29
 
30
namespace clang {
31
 
32
class AnalysisDeclContext;
33
class CXXBindTemporaryExpr;
34
class FunctionDecl;
35
class PostOrderCFGView;
36
class Stmt;
37
class VarDecl;
38
 
39
namespace consumed {
40
 
41
  class ConsumedStmtVisitor;
42
 
43
  enum ConsumedState {
44
    // No state information for the given variable.
45
    CS_None,
46
 
47
    CS_Unknown,
48
    CS_Unconsumed,
49
    CS_Consumed
50
  };
51
 
52
  using OptionalNotes = SmallVector<PartialDiagnosticAt, 1>;
53
  using DelayedDiag = std::pair<PartialDiagnosticAt, OptionalNotes>;
54
  using DiagList = std::list<DelayedDiag>;
55
 
56
  class ConsumedWarningsHandlerBase {
57
  public:
58
    virtual ~ConsumedWarningsHandlerBase();
59
 
60
    /// Emit the warnings and notes left by the analysis.
61
    virtual void emitDiagnostics() {}
62
 
63
    /// Warn that a variable's state doesn't match at the entry and exit
64
    /// of a loop.
65
    ///
66
    /// \param Loc -- The location of the end of the loop.
67
    ///
68
    /// \param VariableName -- The name of the variable that has a mismatched
69
    /// state.
70
    virtual void warnLoopStateMismatch(SourceLocation Loc,
71
                                       StringRef VariableName) {}
72
 
73
    /// Warn about parameter typestate mismatches upon return.
74
    ///
75
    /// \param Loc -- The SourceLocation of the return statement.
76
    ///
77
    /// \param ExpectedState -- The state the return value was expected to be
78
    /// in.
79
    ///
80
    /// \param ObservedState -- The state the return value was observed to be
81
    /// in.
82
    virtual void warnParamReturnTypestateMismatch(SourceLocation Loc,
83
                                                  StringRef VariableName,
84
                                                  StringRef ExpectedState,
85
                                                  StringRef ObservedState) {}
86
 
87
    // FIXME: Add documentation.
88
    virtual void warnParamTypestateMismatch(SourceLocation LOC,
89
                                            StringRef ExpectedState,
90
                                            StringRef ObservedState) {}
91
 
92
    // FIXME: This can be removed when the attr propagation fix for templated
93
    //        classes lands.
94
    /// Warn about return typestates set for unconsumable types.
95
    ///
96
    /// \param Loc -- The location of the attributes.
97
    ///
98
    /// \param TypeName -- The name of the unconsumable type.
99
    virtual void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
100
                                                        StringRef TypeName) {}
101
 
102
    /// Warn about return typestate mismatches.
103
    ///
104
    /// \param Loc -- The SourceLocation of the return statement.
105
    ///
106
    /// \param ExpectedState -- The state the return value was expected to be
107
    /// in.
108
    ///
109
    /// \param ObservedState -- The state the return value was observed to be
110
    /// in.
111
    virtual void warnReturnTypestateMismatch(SourceLocation Loc,
112
                                             StringRef ExpectedState,
113
                                             StringRef ObservedState) {}
114
 
115
    /// Warn about use-while-consumed errors.
116
    /// \param MethodName -- The name of the method that was incorrectly
117
    /// invoked.
118
    ///
119
    /// \param State -- The state the object was used in.
120
    ///
121
    /// \param Loc -- The SourceLocation of the method invocation.
122
    virtual void warnUseOfTempInInvalidState(StringRef MethodName,
123
                                             StringRef State,
124
                                             SourceLocation Loc) {}
125
 
126
    /// Warn about use-while-consumed errors.
127
    /// \param MethodName -- The name of the method that was incorrectly
128
    /// invoked.
129
    ///
130
    /// \param State -- The state the object was used in.
131
    ///
132
    /// \param VariableName -- The name of the variable that holds the unique
133
    /// value.
134
    ///
135
    /// \param Loc -- The SourceLocation of the method invocation.
136
    virtual void warnUseInInvalidState(StringRef MethodName,
137
                                       StringRef VariableName,
138
                                       StringRef State,
139
                                       SourceLocation Loc) {}
140
  };
141
 
142
  class ConsumedStateMap {
143
    using VarMapType = llvm::DenseMap<const VarDecl *, ConsumedState>;
144
    using TmpMapType =
145
        llvm::DenseMap<const CXXBindTemporaryExpr *, ConsumedState>;
146
 
147
  protected:
148
    bool Reachable = true;
149
    const Stmt *From = nullptr;
150
    VarMapType VarMap;
151
    TmpMapType TmpMap;
152
 
153
  public:
154
    ConsumedStateMap() = default;
155
    ConsumedStateMap(const ConsumedStateMap &Other)
156
        : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap) {}
157
 
158
    /// Warn if any of the parameters being tracked are not in the state
159
    /// they were declared to be in upon return from a function.
160
    void checkParamsForReturnTypestate(SourceLocation BlameLoc,
161
      ConsumedWarningsHandlerBase &WarningsHandler) const;
162
 
163
    /// Clear the TmpMap.
164
    void clearTemporaries();
165
 
166
    /// Get the consumed state of a given variable.
167
    ConsumedState getState(const VarDecl *Var) const;
168
 
169
    /// Get the consumed state of a given temporary value.
170
    ConsumedState getState(const CXXBindTemporaryExpr *Tmp) const;
171
 
172
    /// Merge this state map with another map.
173
    void intersect(const ConsumedStateMap &Other);
174
 
175
    void intersectAtLoopHead(const CFGBlock *LoopHead, const CFGBlock *LoopBack,
176
      const ConsumedStateMap *LoopBackStates,
177
      ConsumedWarningsHandlerBase &WarningsHandler);
178
 
179
    /// Return true if this block is reachable.
180
    bool isReachable() const { return Reachable; }
181
 
182
    /// Mark the block as unreachable.
183
    void markUnreachable();
184
 
185
    /// Set the source for a decision about the branching of states.
186
    /// \param Source -- The statement that was the origin of a branching
187
    /// decision.
188
    void setSource(const Stmt *Source) { this->From = Source; }
189
 
190
    /// Set the consumed state of a given variable.
191
    void setState(const VarDecl *Var, ConsumedState State);
192
 
193
    /// Set the consumed state of a given temporary value.
194
    void setState(const CXXBindTemporaryExpr *Tmp, ConsumedState State);
195
 
196
    /// Remove the temporary value from our state map.
197
    void remove(const CXXBindTemporaryExpr *Tmp);
198
 
199
    /// Tests to see if there is a mismatch in the states stored in two
200
    /// maps.
201
    ///
202
    /// \param Other -- The second map to compare against.
203
    bool operator!=(const ConsumedStateMap *Other) const;
204
  };
205
 
206
  class ConsumedBlockInfo {
207
    std::vector<std::unique_ptr<ConsumedStateMap>> StateMapsArray;
208
    std::vector<unsigned int> VisitOrder;
209
 
210
  public:
211
    ConsumedBlockInfo() = default;
212
 
213
    ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph)
214
        : StateMapsArray(NumBlocks), VisitOrder(NumBlocks, 0) {
215
      unsigned int VisitOrderCounter = 0;
216
      for (const auto BI : *SortedGraph)
217
        VisitOrder[BI->getBlockID()] = VisitOrderCounter++;
218
    }
219
 
220
    bool allBackEdgesVisited(const CFGBlock *CurrBlock,
221
                             const CFGBlock *TargetBlock);
222
 
223
    void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap,
224
                 std::unique_ptr<ConsumedStateMap> &OwnedStateMap);
225
    void addInfo(const CFGBlock *Block,
226
                 std::unique_ptr<ConsumedStateMap> StateMap);
227
 
228
    ConsumedStateMap* borrowInfo(const CFGBlock *Block);
229
 
230
    void discardInfo(const CFGBlock *Block);
231
 
232
    std::unique_ptr<ConsumedStateMap> getInfo(const CFGBlock *Block);
233
 
234
    bool isBackEdge(const CFGBlock *From, const CFGBlock *To);
235
    bool isBackEdgeTarget(const CFGBlock *Block);
236
  };
237
 
238
  /// A class that handles the analysis of uniqueness violations.
239
  class ConsumedAnalyzer {
240
    ConsumedBlockInfo BlockInfo;
241
    std::unique_ptr<ConsumedStateMap> CurrStates;
242
 
243
    ConsumedState ExpectedReturnState;
244
 
245
    void determineExpectedReturnState(AnalysisDeclContext &AC,
246
                                      const FunctionDecl *D);
247
    bool splitState(const CFGBlock *CurrBlock,
248
                    const ConsumedStmtVisitor &Visitor);
249
 
250
  public:
251
    ConsumedWarningsHandlerBase &WarningsHandler;
252
 
253
    ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler)
254
        : WarningsHandler(WarningsHandler) {}
255
 
256
    ConsumedState getExpectedReturnState() const { return ExpectedReturnState; }
257
 
258
    /// Check a function's CFG for consumed violations.
259
    ///
260
    /// We traverse the blocks in the CFG, keeping track of the state of each
261
    /// value who's type has uniquness annotations.  If methods are invoked in
262
    /// the wrong state a warning is issued.  Each block in the CFG is traversed
263
    /// exactly once.
264
    void run(AnalysisDeclContext &AC);
265
  };
266
 
267
} // namespace consumed
268
 
269
} // namespace clang
270
 
271
#endif // LLVM_CLANG_ANALYSIS_ANALYSES_CONSUMED_H