public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/98835] New: False positive -Wclass-memaccess with class with ref-qualified copy-assignment operator
@ 2021-01-26  9:33 jchl at arista dot com
  2021-01-26 19:38 ` [Bug c++/98835] " msebor at gcc dot gnu.org
  2021-02-01 15:48 ` cvs-commit at gcc dot gnu.org
  0 siblings, 2 replies; 3+ messages in thread
From: jchl at arista dot com @ 2021-01-26  9:33 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98835

            Bug ID: 98835
           Summary: False positive -Wclass-memaccess with class with
                    ref-qualified copy-assignment operator
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jchl at arista dot com
  Target Milestone: ---

Consider the following code:

  #include <type_traits>
  #include <cstring>

  class Good {
   public:
      Good & operator=(Good const &) = default;
  };

  class Bad {
   public:
      Bad & operator=(Bad const &) & = default;
  };

  template<typename T>
  void test() {
      static_assert(std::is_trivially_copyable_v<T>);
      T value1;
      T value2;
      std::memcpy(&value1, &value2, sizeof(T));
  }

  int main() {
      test<Good>();
      test<Bad>();
  }

[See: https://godbolt.org/z/4vj9GT ]

GCC trunk on x86_64 incorrectly gives the following warning:

  <source>: In instantiation of 'void test() [with T = Bad]':
  <source>:24:15:   required from here
  <source>:19:16: warning: 'void* memcpy(void*, const void*, size_t)' writing
to an object of type 'class Bad' with no trivial copy-assignment; use
copy-assignment or copy-initialization instead [-Wclass-memaccess]
     19 |     std::memcpy(&value1, &value2, sizeof(T));
        |     ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Since both Good and Bad have trivial copy-assignment operators and are
trivially copyable, both types are eligible to be memcpy'd; the
ref-qualification of the assignment operator shouldn't be relevant.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c++/98835] False positive -Wclass-memaccess with class with ref-qualified copy-assignment operator
  2021-01-26  9:33 [Bug c++/98835] New: False positive -Wclass-memaccess with class with ref-qualified copy-assignment operator jchl at arista dot com
@ 2021-01-26 19:38 ` msebor at gcc dot gnu.org
  2021-02-01 15:48 ` cvs-commit at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: msebor at gcc dot gnu.org @ 2021-01-26 19:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98835

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
           Keywords|                            |diagnostic
                 CC|                            |msebor at gcc dot gnu.org
         Resolution|---                         |INVALID

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
The warning is issued on the basis that the left-hand operand of Bad's
assignment cannot be a temporary.  I.e., that this isn't valid: Bad() = Bad(). 
In the modified test case below the warning detects the memcpy call bypassing
the constraint the assignment operator puts on assigning to objects of the
class.  So unless there's a compelling use case showing otherwise I'm inclined
to say the warning is justified and helpful here (its wording shouldn't be
expected to perfectly reflect all the subtleties involved in the decision). 
There isn't a test case for this in the test suite so let me add this one.

  class Bad {
   public:
      Bad* operator& () { return this; }
      Bad & operator=(Bad const &) & = default;
  };

  template<typename T>
  void test() {
      static_assert (__has_trivial_copy (T));
      // T () = T ();                     // error
      memcpy (&T (), &T (), sizeof(T));   // warning
  }

  int main() {
      test<Bad>();
  }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug c++/98835] False positive -Wclass-memaccess with class with ref-qualified copy-assignment operator
  2021-01-26  9:33 [Bug c++/98835] New: False positive -Wclass-memaccess with class with ref-qualified copy-assignment operator jchl at arista dot com
  2021-01-26 19:38 ` [Bug c++/98835] " msebor at gcc dot gnu.org
@ 2021-02-01 15:48 ` cvs-commit at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2021-02-01 15:48 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98835

--- Comment #2 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>:

https://gcc.gnu.org/g:c2f8e378d64f65645e5f9c41a8221ca102c71208

commit r11-7014-gc2f8e378d64f65645e5f9c41a8221ca102c71208
Author: Martin Sebor <msebor@redhat.com>
Date:   Mon Feb 1 08:42:58 2021 -0700

    Verify a warning for a class with a ref-qualified assignment (PR
c++/98835).

    gcc/testsuite/ChangeLog:
            PR c++/98835
            * g++.dg/Wclass-memaccess-6.C: New test.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-02-01 15:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-26  9:33 [Bug c++/98835] New: False positive -Wclass-memaccess with class with ref-qualified copy-assignment operator jchl at arista dot com
2021-01-26 19:38 ` [Bug c++/98835] " msebor at gcc dot gnu.org
2021-02-01 15:48 ` cvs-commit at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).