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

            Bug ID: 81327
           Summary: cast to void* does not suppress -Wclass-memaccess
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

In cases where the -Wclass-memaccess warning (new in GCC 8) points out benign
code the warning can be suppressed by casting a pointer to the class object to
char*.   In Clang that implements a similar warning
(-Wdynamic-class-memaccess), the warning can also be suppressed by casting the
pointer to void* but the same doesn't work in GCC.  It's been suggested that it
might be nice if GCC also recognized a void* cast as a suppression mechanism. 
(Unfortunately, where the warning is implemented in the GCC C++ front end an
explicit void* cast is indistinguishable from the implicit conversion to the
void* argument to the raw memory function.)

$ cat t.C && gcc -S -Wall t.C
struct S { virtual ~S (); };

void f (struct S *s)
{
  __builtin_memset (s, 0, sizeof *s);
}

void g (struct S *s)
{
  __builtin_memset ((void*)s, 0, sizeof *s);
}

void h (struct S *s)
{
  __builtin_memset ((char*)s, 0, sizeof *s);
}

t.C: In function ‘void f(S*)’:
t.C:5:36: warning: ‘void* __builtin_memset(void*, int, long unsigned int)’
clearing an object of type ‘struct S’ with no trivial copy-assignment; use
assignment or value-initialization instead [-Wclass-memaccess]
   __builtin_memset (s, 0, sizeof *s);
                                    ^
t.C:1:8: note: ‘struct S’ declared here
 struct S { virtual ~S (); };
        ^
t.C: In function ‘void g(S*)’:
t.C:10:43: warning: ‘void* __builtin_memset(void*, int, long unsigned int)’
clearing an object of type ‘struct S’ with no trivial copy-assignment; use
assignment or value-initialization instead [-Wclass-memaccess]
   __builtin_memset ((void*)s, 0, sizeof *s);
                                           ^
t.C:1:8: note: ‘struct S’ declared here
 struct S { virtual ~S (); };
        ^

Clang output for the same test case:

$ clang -S -Wall t.C
t.C:5:21: warning: destination for this '__builtin_memset' call is a pointer to
      dynamic class 'S'; vtable pointer will be overwritten
      [-Wdynamic-class-memaccess]
  __builtin_memset (s, 0, sizeof *s);
  ~~~~~~~~~~~~~~~~  ^
t.C:5:21: note: explicitly cast the pointer to silence this warning
  __builtin_memset (s, 0, sizeof *s);
                    ^
                    (void*)
1 warning generated.

Reply via email to