[clang] [clang-tools-extra] [clang-tidy] Add support for use-after-suspend to bugprone-use-after-move (PR #172566)
Yanzuo Liu via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 8 06:14:48 PST 2026
================
@@ -559,21 +595,56 @@ void UseAfterMoveCheck::check(const MatchFinder::MatchResult &Result) {
ContainingCtorInit->IgnoreImplicit())
BeforeMove = false;
if (!BeforeMove)
- CodeBlocks.push_back(Init->getInit());
+ CodeBlocks.push_back({ContainingCtor, Init->getInit()});
}
}
} else if (ContainingLambda) {
- CodeBlocks.push_back(ContainingLambda->getBody());
+ CodeBlocks.push_back(
+ {ContainingLambda->getCallOperator(), ContainingLambda->getBody()});
} else if (ContainingFunc) {
- CodeBlocks.push_back(ContainingFunc->getBody());
+ CodeBlocks.push_back({ContainingFunc, ContainingFunc->getBody()});
}
- for (Stmt *CodeBlock : CodeBlocks) {
+ for (auto [ContainingDecl, CodeBlock] : CodeBlocks) {
UseAfterMoveFinder Finder(Result.Context, InvalidationFunctions,
ReinitializationFunctions);
- if (auto Use = Finder.find(CodeBlock, MovingCall, Arg))
- emitDiagnostic(MovingCall, Arg, *Use, this, Result.Context,
- determineMoveType(MoveDecl));
+ if (Arg) {
+ // Non-coroutine cases
+ if (auto Use = Finder.find(CodeBlock, MovingCall, Arg))
+ emitDiagnostic(MovingCall, Arg, *Use, this, Result.Context,
+ determineMoveType(MoveDecl));
+ } else {
+ // Coroutine cases (use-after-suspend, to catch pointers to thread-locals)
+ llvm::SmallVector<const DeclRefExpr *> DeclRefs;
+ // Find all local variables declared inside this code block
+ auto InterestingCallMatcher = callExpr(
+ callee(
+ functionDecl(matchers::matchesAnyListedRegexName(NonlocalAccessors))),
+ unless(hasParent(memberExpr(
+ hasDeclaration(functionDecl(unless(returns(hasCanonicalType(
+ anyOf(referenceType(), pointerType()))))))))));
+ auto DeclsMatcher =
+ declRefExpr(to(varDecl(unless(isImplicit()),
+ hasDeclContext(equalsNode(ContainingDecl)),
+ hasType(hasUnqualifiedDesugaredType(
+ anyOf(pointerType(), referenceType()))),
+ hasInitializer(anyOf(
+ InterestingCallMatcher,
+ hasDescendant(InterestingCallMatcher))))))
+ .bind("declref");
+ for (const auto &Bound :
+ match(findAll(DeclsMatcher), *CodeBlock, *Result.Context)) {
+ DeclRefs.push_back(Bound.getNodeAs<DeclRefExpr>("declref"));
+ }
+ for (const DeclRefExpr *DeclRef : DeclRefs) {
+ if (auto Use = Finder.find(CodeBlock, MovingCall, DeclRef)) {
+ emitDiagnostic(MovingCall, DeclRef, *Use, this, Result.Context,
+ isa<CoroutineSuspendExpr>(MovingCall)
----------------
zwuis wrote:
Can we use `assert` instead?
https://github.com/llvm/llvm-project/pull/172566
More information about the cfe-commits
mailing list