Author: mboehme Date: Mon Aug 13 07:24:52 2018 New Revision: 339571 URL: http://llvm.org/viewvc/llvm-project?rev=339571&view=rev Log: [clang-tidy] Recognize [[clang::reinitializes]] attribute in bugprone-use-after-move
Summary: This allows member functions to be marked as reinitializing the object. After a moved-from object has been reinitialized, the check will no longer consider it to be in an indeterminate state. The patch that adds the attribute itself is at https://reviews.llvm.org/D49911 Reviewers: ilya-biryukov, aaron.ballman, alexfh, hokein, rsmith Reviewed By: aaron.ballman Subscribers: dblaikie, xazax.hun, cfe-commits Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D49910 Modified: clang-tools-extra/trunk/clang-tidy/bugprone/UseAfterMoveCheck.cpp clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-use-after-move.rst clang-tools-extra/trunk/test/clang-tidy/bugprone-use-after-move.cpp Modified: clang-tools-extra/trunk/clang-tidy/bugprone/UseAfterMoveCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/UseAfterMoveCheck.cpp?rev=339571&r1=339570&r2=339571&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/bugprone/UseAfterMoveCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/bugprone/UseAfterMoveCheck.cpp Mon Aug 13 07:24:52 2018 @@ -308,6 +308,10 @@ void UseAfterMoveFinder::getReinits( cxxMemberCallExpr( on(allOf(DeclRefMatcher, StandardSmartPointerTypeMatcher)), callee(cxxMethodDecl(hasName("reset")))), + // Methods that have the [[clang::reinitializes]] attribute. + cxxMemberCallExpr( + on(DeclRefMatcher), + callee(cxxMethodDecl(hasAttr(clang::attr::Reinitializes)))), // Passing variable to a function as a non-const pointer. callExpr(forEachArgumentWithParam( unaryOperator(hasOperatorName("&"), Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-use-after-move.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-use-after-move.rst?rev=339571&r1=339570&r2=339571&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-use-after-move.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-use-after-move.rst Mon Aug 13 07:24:52 2018 @@ -178,6 +178,9 @@ The check considers a variable to be rei - ``reset()`` is called on the variable and the variable is of type ``std::unique_ptr``, ``std::shared_ptr`` or ``std::weak_ptr``. + - A member function marked with the ``[[clang::reinitializes]]`` attribute is + called on the variable. + If the variable in question is a struct and an individual member variable of that struct is written to, the check does not consider this to be a reinitialization -- even if, eventually, all member variables of the struct are Modified: clang-tools-extra/trunk/test/clang-tidy/bugprone-use-after-move.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/bugprone-use-after-move.cpp?rev=339571&r1=339570&r2=339571&view=diff ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/bugprone-use-after-move.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/bugprone-use-after-move.cpp Mon Aug 13 07:24:52 2018 @@ -107,6 +107,15 @@ public: int i; }; +template <class T> +class AnnotatedContainer { +public: + AnnotatedContainer(); + + void foo() const; + [[clang::reinitializes]] void clear(); +}; + //////////////////////////////////////////////////////////////////////////////// // General tests. @@ -898,6 +907,32 @@ void standardSmartPointerResetIsReinit() } } +void reinitAnnotation() { + { + AnnotatedContainer<int> obj; + std::move(obj); + obj.foo(); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: 'obj' used after it was + // CHECK-MESSAGES: [[@LINE-3]]:5: note: move occurred here + } + { + AnnotatedContainer<int> obj; + std::move(obj); + obj.clear(); + obj.foo(); + } + { + // Calling clear() on a different object to the one that was moved is not + // considered a reinitialization. + AnnotatedContainer<int> obj1, obj2; + std::move(obj1); + obj2.clear(); + obj1.foo(); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: 'obj1' used after it was + // CHECK-MESSAGES: [[@LINE-4]]:5: note: move occurred here + } +} + //////////////////////////////////////////////////////////////////////////////// // Tests related to order of evaluation within expressions _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits