https://github.com/higher-performance updated https://github.com/llvm/llvm-project/pull/114255
>From 24ab723b8479e4cafb5c39d3def703466d6e504d Mon Sep 17 00:00:00 2001 From: higher-performance <higher.performance.git...@gmail.com> Date: Wed, 30 Oct 2024 12:01:00 -0400 Subject: [PATCH] Extend bugprone-use-after-move check to handle std::optional::reset() and std::any::reset() similarly to smart pointers --- .../clang-tidy/bugprone/UseAfterMoveCheck.cpp | 16 ++++++----- .../checkers/bugprone/use-after-move.cpp | 27 ++++++++++++++++++- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index 8f4b5e8092ddaa..38ca539efd07da 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -242,7 +242,7 @@ void UseAfterMoveFinder::getUsesAndReinits( }); } -bool isStandardSmartPointer(const ValueDecl *VD) { +bool isStandardResettable(const ValueDecl *VD) { const Type *TheType = VD->getType().getNonReferenceType().getTypePtrOrNull(); if (!TheType) return false; @@ -256,7 +256,8 @@ bool isStandardSmartPointer(const ValueDecl *VD) { return false; StringRef Name = ID->getName(); - if (Name != "unique_ptr" && Name != "shared_ptr" && Name != "weak_ptr") + if (Name != "unique_ptr" && Name != "shared_ptr" && Name != "weak_ptr" && + Name != "optional" && Name != "any") return false; return RecordDecl->getDeclContext()->isStdNamespace(); @@ -279,7 +280,7 @@ void UseAfterMoveFinder::getDeclRefs( if (DeclRef && BlockMap->blockContainingStmt(DeclRef) == Block) { // Ignore uses of a standard smart pointer that don't dereference the // pointer. - if (Operator || !isStandardSmartPointer(DeclRef->getDecl())) { + if (Operator || !isStandardResettable(DeclRef->getDecl())) { DeclRefs->insert(DeclRef); } } @@ -315,9 +316,10 @@ void UseAfterMoveFinder::getReinits( "::std::unordered_map", "::std::unordered_multiset", "::std::unordered_multimap")))))); - auto StandardSmartPointerTypeMatcher = hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(cxxRecordDecl(hasAnyName( - "::std::unique_ptr", "::std::shared_ptr", "::std::weak_ptr")))))); + auto StandardResettableTypeMatcher = hasType( + hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl( + hasAnyName("::std::unique_ptr", "::std::shared_ptr", + "::std::weak_ptr", "::std::optional", "::std::any")))))); // Matches different types of reinitialization. auto ReinitMatcher = @@ -340,7 +342,7 @@ void UseAfterMoveFinder::getReinits( callee(cxxMethodDecl(hasAnyName("clear", "assign")))), // reset() on standard smart pointers. cxxMemberCallExpr( - on(expr(DeclRefMatcher, StandardSmartPointerTypeMatcher)), + on(expr(DeclRefMatcher, StandardResettableTypeMatcher)), callee(cxxMethodDecl(hasName("reset")))), // Methods that have the [[clang::reinitializes]] attribute. cxxMemberCallExpr( diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/use-after-move.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/use-after-move.cpp index 6a4e3990e36dc5..59ce929ee17d82 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/use-after-move.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/use-after-move.cpp @@ -33,6 +33,17 @@ struct weak_ptr { bool expired() const; }; +template <typename T> +struct optional { + optional(); + void reset(); +}; + +struct any { + any(); + void reset(); +}; + template <typename T1, typename T2> struct pair {}; @@ -997,7 +1008,7 @@ void standardContainerAssignIsReinit() { // Resetting the standard smart pointer types using reset() is treated as a // re-initialization. (We don't test std::weak_ptr<> because it can't be // dereferenced directly.) -void standardSmartPointerResetIsReinit() { +void resetIsReinit() { { std::unique_ptr<A> ptr; std::move(ptr); @@ -1010,6 +1021,20 @@ void standardSmartPointerResetIsReinit() { ptr.reset(new A); *ptr; } + { + std::optional<A> opt; + std::move(opt); + opt.reset(); + std::optional<A> opt2 = opt; + (void)opt2; + } + { + std::any a; + std::move(a); + a.reset(); + std::any a2 = a; + (void)a2; + } } void reinitAnnotation() { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits