[clang-tools-extra] r339571 - [clang-tidy] Recognize [[clang::reinitializes]] attribute in bugprone-use-after-move
Martin Bohme via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 13 07:24:52 PDT 2018
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
More information about the cfe-commits
mailing list