]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Allow -Wvirtual-move-assign to be more easily ignored
authorOwen Avery <powerboat9.gamer@gmail.com>
Tue, 13 May 2025 21:18:28 +0000 (17:18 -0400)
committerJason Merrill <jason@redhat.com>
Wed, 14 May 2025 02:25:33 +0000 (22:25 -0400)
This patch makes it easier to selectively disable
-Wvirtual-move-assign by allowing diagnostic pragmas on
base class move assignment operators to suppress such
warnings.

gcc/cp/ChangeLog:

* method.cc (synthesized_method_walk): Check whether
-Wvirtual-move-assign is enabled at the location of a base
class's move assignment operator.

gcc/testsuite/ChangeLog:

* g++.dg/warn/ignore-virtual-move-assign.C: New test.

Co-authored-by: Jason Merrill <jason@redhat.com>
Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
gcc/cp/method.cc
gcc/testsuite/g++.dg/warn/ignore-virtual-move-assign.C [new file with mode: 0644]

index 05c19cf0661e5ed7ee28edac80f246621fdb73a7..092bae27787566241cffa37fb0239a60ef5c6069 100644 (file)
@@ -2949,7 +2949,9 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
          && BINFO_VIRTUAL_P (base_binfo)
          && fn && TREE_CODE (fn) == FUNCTION_DECL
          && move_fn_p (fn) && !trivial_fn_p (fn)
-         && vbase_has_user_provided_move_assign (BINFO_TYPE (base_binfo)))
+         && vbase_has_user_provided_move_assign (BINFO_TYPE (base_binfo))
+         && warning_enabled_at (DECL_SOURCE_LOCATION (fn),
+                                OPT_Wvirtual_move_assign))
        warning (OPT_Wvirtual_move_assign,
                 "defaulted move assignment for %qT calls a non-trivial "
                 "move assignment operator for virtual base %qT",
diff --git a/gcc/testsuite/g++.dg/warn/ignore-virtual-move-assign.C b/gcc/testsuite/g++.dg/warn/ignore-virtual-move-assign.C
new file mode 100644 (file)
index 0000000..73922e6
--- /dev/null
@@ -0,0 +1,45 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wvirtual-move-assign -Wattributes" }
+
+#include <utility>
+
+class A
+{
+  int val;
+
+public:
+  explicit A (int val) : val (val) {}
+
+  A (const A &oth) : val (0) {}
+  A &operator= (const A &oth) { return *this; }
+  A (A &&oth) : val (oth.val) { oth.val = 0; }
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wvirtual-move-assign"
+  A &operator= (A &&oth)
+  {
+    val += oth.val;
+    oth.val = 0;
+    return *this;
+  }
+#pragma GCC diagnostic pop
+};
+
+class B : virtual A
+{
+public:
+  B () : A (12) {}
+  B &operator= (B &&) = default;
+};
+
+class C : virtual A
+{
+public:
+  C () : A (12) {}
+};
+
+void
+test_fn ()
+{
+  C x, y;
+  x = std::move (y);
+}