@@ -54,13 +54,13 @@ class UseAfterMoveFinder {
54
54
// occurs after 'MovingCall' (the expression that performs the move). If a
55
55
// use-after-move is found, writes information about it to 'TheUseAfterMove'.
56
56
// Returns whether a use-after-move was found.
57
- bool find (Stmt *CodeBlock, const Expr *MovingCall,
58
- const DeclRefExpr *MovedVariable, UseAfterMove *TheUseAfterMove );
57
+ std::optional<UseAfterMove> find (Stmt *CodeBlock, const Expr *MovingCall,
58
+ const DeclRefExpr *MovedVariable);
59
59
60
60
private:
61
- bool findInternal (const CFGBlock *Block, const Expr *MovingCall ,
62
- const ValueDecl *MovedVariable ,
63
- UseAfterMove *TheUseAfterMove );
61
+ std::optional<UseAfterMove> findInternal (const CFGBlock *Block,
62
+ const Expr *MovingCall ,
63
+ const ValueDecl *MovedVariable );
64
64
void getUsesAndReinits (const CFGBlock *Block, const ValueDecl *MovedVariable,
65
65
llvm::SmallVectorImpl<const DeclRefExpr *> *Uses,
66
66
llvm::SmallPtrSetImpl<const Stmt *> *Reinits);
@@ -95,9 +95,9 @@ static StatementMatcher inDecltypeOrTemplateArg() {
95
95
UseAfterMoveFinder::UseAfterMoveFinder (ASTContext *TheContext)
96
96
: Context(TheContext) {}
97
97
98
- bool UseAfterMoveFinder::find (Stmt *CodeBlock, const Expr *MovingCall,
99
- const DeclRefExpr *MovedVariable ,
100
- UseAfterMove *TheUseAfterMove ) {
98
+ std::optional<UseAfterMove>
99
+ UseAfterMoveFinder::find (Stmt *CodeBlock, const Expr *MovingCall ,
100
+ const DeclRefExpr *MovedVariable ) {
101
101
// Generate the CFG manually instead of through an AnalysisDeclContext because
102
102
// it seems the latter can't be used to generate a CFG for the body of a
103
103
// lambda.
@@ -111,7 +111,7 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall,
111
111
std::unique_ptr<CFG> TheCFG =
112
112
CFG::buildCFG (nullptr , CodeBlock, Context, Options);
113
113
if (!TheCFG)
114
- return false ;
114
+ return std::nullopt ;
115
115
116
116
Sequence = std::make_unique<ExprSequence>(TheCFG.get (), CodeBlock, Context);
117
117
BlockMap = std::make_unique<StmtToBlockMap>(TheCFG.get (), Context);
@@ -125,10 +125,10 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall,
125
125
MoveBlock = &TheCFG->getEntry ();
126
126
}
127
127
128
- bool Found = findInternal (MoveBlock, MovingCall, MovedVariable-> getDecl (),
129
- TheUseAfterMove );
128
+ auto TheUseAfterMove =
129
+ findInternal (MoveBlock, MovingCall, MovedVariable-> getDecl () );
130
130
131
- if (Found ) {
131
+ if (TheUseAfterMove ) {
132
132
if (const CFGBlock *UseBlock =
133
133
BlockMap->blockContainingStmt (TheUseAfterMove->DeclRef )) {
134
134
// Does the use happen in a later loop iteration than the move?
@@ -142,15 +142,14 @@ bool UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall,
142
142
: CFA.isReachable (UseBlock, MoveBlock);
143
143
}
144
144
}
145
- return Found ;
145
+ return TheUseAfterMove ;
146
146
}
147
147
148
- bool UseAfterMoveFinder::findInternal (const CFGBlock *Block,
149
- const Expr *MovingCall,
150
- const ValueDecl *MovedVariable,
151
- UseAfterMove *TheUseAfterMove) {
148
+ std::optional<UseAfterMove>
149
+ UseAfterMoveFinder::findInternal (const CFGBlock *Block, const Expr *MovingCall,
150
+ const ValueDecl *MovedVariable) {
152
151
if (Visited.count (Block))
153
- return false ;
152
+ return std::nullopt ;
154
153
155
154
// Mark the block as visited (except if this is the block containing the
156
155
// std::move() and it's being visited the first time).
@@ -189,17 +188,18 @@ bool UseAfterMoveFinder::findInternal(const CFGBlock *Block,
189
188
}
190
189
191
190
if (!HaveSavingReinit) {
192
- TheUseAfterMove->DeclRef = Use;
191
+ UseAfterMove TheUseAfterMove;
192
+ TheUseAfterMove.DeclRef = Use;
193
193
194
194
// Is this a use-after-move that depends on order of evaluation?
195
195
// This is the case if the move potentially comes after the use (and we
196
196
// already know that use potentially comes after the move, which taken
197
197
// together tells us that the ordering is unclear).
198
- TheUseAfterMove-> EvaluationOrderUndefined =
198
+ TheUseAfterMove. EvaluationOrderUndefined =
199
199
MovingCall != nullptr &&
200
200
Sequence->potentiallyAfter (MovingCall, Use);
201
201
202
- return true ;
202
+ return TheUseAfterMove ;
203
203
}
204
204
}
205
205
}
@@ -208,12 +208,15 @@ bool UseAfterMoveFinder::findInternal(const CFGBlock *Block,
208
208
// successors.
209
209
if (Reinits.empty ()) {
210
210
for (const auto &Succ : Block->succs ()) {
211
- if (Succ && findInternal (Succ, nullptr , MovedVariable, TheUseAfterMove))
212
- return true ;
211
+ if (Succ) {
212
+ if (auto Found = findInternal (Succ, nullptr , MovedVariable)) {
213
+ return Found;
214
+ }
215
+ }
213
216
}
214
217
}
215
218
216
- return false ;
219
+ return std::nullopt ;
217
220
}
218
221
219
222
void UseAfterMoveFinder::getUsesAndReinits (
@@ -518,9 +521,8 @@ void UseAfterMoveCheck::check(const MatchFinder::MatchResult &Result) {
518
521
519
522
for (Stmt *CodeBlock : CodeBlocks) {
520
523
UseAfterMoveFinder Finder (Result.Context );
521
- UseAfterMove Use;
522
- if (Finder.find (CodeBlock, MovingCall, Arg, &Use))
523
- emitDiagnostic (MovingCall, Arg, Use, this , Result.Context ,
524
+ if (auto Use = Finder.find (CodeBlock, MovingCall, Arg))
525
+ emitDiagnostic (MovingCall, Arg, *Use, this , Result.Context ,
524
526
determineMoveType (MoveDecl));
525
527
}
526
528
}
0 commit comments