@@ -48,7 +48,7 @@ struct UseAfterMove {
48
48
// / various internal helper functions).
49
49
class UseAfterMoveFinder {
50
50
public:
51
- UseAfterMoveFinder (ASTContext *TheContext);
51
+ UseAfterMoveFinder (ASTContext *TheContext, bool IgnoreNonDerefSmartPtrs );
52
52
53
53
// Within the given code block, finds the first use of 'MovedVariable' that
54
54
// occurs after 'MovingCall' (the expression that performs the move). If a
@@ -71,6 +71,7 @@ class UseAfterMoveFinder {
71
71
llvm::SmallPtrSetImpl<const DeclRefExpr *> *DeclRefs);
72
72
73
73
ASTContext *Context;
74
+ const bool IgnoreNonDerefSmartPtrs;
74
75
std::unique_ptr<ExprSequence> Sequence;
75
76
std::unique_ptr<StmtToBlockMap> BlockMap;
76
77
llvm::SmallPtrSet<const CFGBlock *, 8 > Visited;
@@ -92,8 +93,9 @@ static StatementMatcher inDecltypeOrTemplateArg() {
92
93
hasAncestor (expr (hasUnevaluatedContext ())));
93
94
}
94
95
95
- UseAfterMoveFinder::UseAfterMoveFinder (ASTContext *TheContext)
96
- : Context(TheContext) {}
96
+ UseAfterMoveFinder::UseAfterMoveFinder (ASTContext *TheContext,
97
+ bool IgnoreNonDerefSmartPtrs)
98
+ : Context(TheContext), IgnoreNonDerefSmartPtrs(IgnoreNonDerefSmartPtrs) {}
97
99
98
100
std::optional<UseAfterMove>
99
101
UseAfterMoveFinder::find (Stmt *CodeBlock, const Expr *MovingCall,
@@ -275,11 +277,13 @@ void UseAfterMoveFinder::getDeclRefs(
275
277
DeclRefs](const ArrayRef<BoundNodes> Matches) {
276
278
for (const auto &Match : Matches) {
277
279
const auto *DeclRef = Match.getNodeAs <DeclRefExpr>(" declref" );
278
- const auto *Operator = Match.getNodeAs <CXXOperatorCallExpr>(" operator" );
279
280
if (DeclRef && BlockMap->blockContainingStmt (DeclRef) == Block) {
280
281
// Ignore uses of a standard smart pointer that don't dereference the
281
282
// pointer.
282
- if (Operator || !isStandardSmartPointer (DeclRef->getDecl ())) {
283
+ const auto *Operator =
284
+ Match.getNodeAs <CXXOperatorCallExpr>(" operator" );
285
+ if (Operator || !IgnoreNonDerefSmartPtrs ||
286
+ !isStandardSmartPointer (DeclRef->getDecl ())) {
283
287
DeclRefs->insert (DeclRef);
284
288
}
285
289
}
@@ -429,6 +433,13 @@ static void emitDiagnostic(const Expr *MovingCall, const DeclRefExpr *MoveArg,
429
433
<< IsMove;
430
434
}
431
435
}
436
+ UseAfterMoveCheck::UseAfterMoveCheck (StringRef Name, ClangTidyContext *Context)
437
+ : ClangTidyCheck(Name, Context),
438
+ IgnoreNonDerefSmartPtrs (Options.get(" IgnoreNonDerefSmartPtrs" , false )) {}
439
+
440
+ void UseAfterMoveCheck::storeOptions (ClangTidyOptions::OptionMap &Opts) {
441
+ Options.store (Opts, " IgnoreNonDerefSmartPtrs" , IgnoreNonDerefSmartPtrs);
442
+ }
432
443
433
444
void UseAfterMoveCheck::registerMatchers (MatchFinder *Finder) {
434
445
// try_emplace is a common maybe-moving function that returns a
@@ -520,7 +531,7 @@ void UseAfterMoveCheck::check(const MatchFinder::MatchResult &Result) {
520
531
}
521
532
522
533
for (Stmt *CodeBlock : CodeBlocks) {
523
- UseAfterMoveFinder Finder (Result.Context );
534
+ UseAfterMoveFinder Finder (Result.Context , IgnoreNonDerefSmartPtrs );
524
535
if (auto Use = Finder.find (CodeBlock, MovingCall, Arg))
525
536
emitDiagnostic (MovingCall, Arg, *Use, this , Result.Context ,
526
537
determineMoveType (MoveDecl));
0 commit comments