llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tools-extra

@llvm/pr-subscribers-clang-tidy

Author: Zeyi Xu (zeyi2)

<details>
<summary>Changes</summary>

The documentation for `cppcoreguidelines-special-member-functions` says that 
`AllowImplicitlyDeletedCopyOrMove` suppresses diagnostics for classes which 
implicitly delete copy or move operations.

While in practice, the check only suppressed the implicitly deleted copy 
operations, the move operations are missing because the user-declared 
destructor prevents their implicit declaration.

This commit suppress that missing-move diagnostic when both copy operations are 
implicitly deleted and no move operation is user-declared.

Godbolt: https://clang-tidy.godbolt.org/z/h1nT84Tee
Closes https://github.com/llvm/llvm-project/issues/196615

---
Full diff: https://github.com/llvm/llvm-project/pull/207586.diff


3 Files Affected:

- (modified) 
clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp 
(+10-1) 
- (modified) clang-tools-extra/docs/ReleaseNotes.rst (+6) 
- (added) 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions-implicit-delete.cpp
 (+31) 


``````````diff
diff --git 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp
 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp
index 1ef64b702cd66..6f2ab250e441b 100644
--- 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp
+++ 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp
@@ -224,10 +224,19 @@ void SpecialMemberFunctionsCheck::checkForMissingMembers(
                    SpecialMemberFunctionKind::CopyAssignment);
   }
 
+  const bool CopyImplicitlyDeleted =
+      HasImplicitDeletedMember(SpecialMemberFunctionKind::CopyConstructor) &&
+      HasImplicitDeletedMember(SpecialMemberFunctionKind::CopyAssignment);
+  const bool MoveMissing =
+      !HasMember(SpecialMemberFunctionKind::MoveConstructor) &&
+      !HasMember(SpecialMemberFunctionKind::MoveAssignment);
+
   if (RequireFive &&
       !(AllowMissingMoveFunctionsWhenCopyIsDeleted &&
         (IsDeleted(SpecialMemberFunctionKind::CopyConstructor) &&
-         IsDeleted(SpecialMemberFunctionKind::CopyAssignment)))) {
+         IsDeleted(SpecialMemberFunctionKind::CopyAssignment))) &&
+      !(AllowImplicitlyDeletedCopyOrMove && CopyImplicitlyDeleted &&
+        MoveMissing)) {
     assert(RequireThree);
     RequireMembers(SpecialMemberFunctionKind::MoveConstructor,
                    SpecialMemberFunctionKind::MoveAssignment);
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 2a980cc089a65..0f6699c5e2270 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -538,6 +538,12 @@ Changes in existing checks
   by fixing a false positive on implicitly generated functions such as
   inherited constructors.
 
+- Improved :doc:`cppcoreguidelines-special-member-functions
+  <clang-tidy/checks/cppcoreguidelines/special-member-functions>` check by
+  fixing a false positive with the `AllowImplicitlyDeletedCopyOrMove` option
+  for classes whose copy operations are implicitly deleted by a non-copyable
+  base class.
+
 - Improved :doc:`cppcoreguidelines-use-enum-class
   <clang-tidy/checks/cppcoreguidelines/use-enum-class>` check by adding the
   `IgnoreMacros` option. When enabled, unscoped ``enum`` declarations within
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions-implicit-delete.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions-implicit-delete.cpp
new file mode 100644
index 0000000000000..45137a30c807c
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions-implicit-delete.cpp
@@ -0,0 +1,31 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t -- \
+// RUN:   -config="{CheckOptions: 
{cppcoreguidelines-special-member-functions.AllowImplicitlyDeletedCopyOrMove: 
true}}"
+
+struct Base {
+  Base(const Base &) = delete;
+  Base &operator=(const Base &) = delete;
+  Base(Base &&) = delete;
+  Base &operator=(Base &&) = delete;
+  ~Base();
+};
+
+struct A : Base {
+  ~A() {}
+};
+
+struct Member {
+  Base B;
+  ~Member() {}
+};
+
+// CHECK-MESSAGES: [[@LINE+1]]:8: warning: class 'B' defines a non-default 
destructor and a move constructor but does not define a move assignment operator
+struct B : Base {
+  ~B() {}
+  B(B &&);
+};
+
+// CHECK-MESSAGES: [[@LINE+1]]:8: warning: class 'C' defines a non-default 
destructor and a move assignment operator but does not define a move constructor
+struct C : Base {
+  ~C() {}
+  C &operator=(C &&);
+};

``````````

</details>


https://github.com/llvm/llvm-project/pull/207586
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to