PR c++/81169 - -Wclass-memaccess illegitimate warning related to volatile
authorMartin Sebor <msebor@redhat.com>
Mon, 26 Jun 2017 17:19:15 +0000 (17:19 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Mon, 26 Jun 2017 17:19:15 +0000 (11:19 -0600)
gcc/cp/ChangeLog:

PR c++/81169
* call.c (maybe_warn_class_memaccess): Preserve explicit conversions
to detect casting away cv-qualifiers.

gcc/testsuite/ChangeLog:

PR c++/81169
* g++.dg/Wclass-memaccess-2.C: New test.

From-SVN: r249660

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/Wclass-memaccess-2.C [new file with mode: 0644]

index 040f7b7..8bc268c 100644 (file)
@@ -1,3 +1,9 @@
+2017-06-26  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/81169
+       * call.c (maybe_warn_class_memaccess): Preserve explicit conversions
+       to detect casting away cv-qualifiers.
+
 2017-06-26  Nathan Sidwell  <nathan@acm.org>
 
        * cp-tree.h (lang_decl_fn): Remove assignment_operator_p field.
index f480611..ff0a26b 100644 (file)
@@ -8340,7 +8340,10 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args)
   if (!dest || !TREE_TYPE (dest) || !POINTER_TYPE_P (TREE_TYPE (dest)))
     return;
 
-  STRIP_NOPS (dest);
+  /* Remove the outermost (usually implicit) conversion to the void*
+     argument type.  */
+  if (TREE_CODE (dest) == NOP_EXPR)
+    dest = TREE_OPERAND (dest, 0);
 
   tree srctype = NULL_TREE;
 
@@ -8357,7 +8360,7 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args)
   if (current_function_decl
       && (DECL_CONSTRUCTOR_P (current_function_decl)
          || DECL_DESTRUCTOR_P (current_function_decl))
-      && is_this_parameter (dest))
+      && is_this_parameter (tree_strip_nop_conversions (dest)))
     {
       tree ctx = DECL_CONTEXT (current_function_decl);
       bool special = same_type_ignoring_top_level_qualifiers_p (ctx, desttype);
index 8b1d5af..d7c906a 100644 (file)
@@ -1,3 +1,8 @@
+2017-06-26  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/81169
+       * g++.dg/Wclass-memaccess-2.C: New test.
+
 2017-06-26  Carl Love  <cel@us.ibm.com>
 
        * gcc.target/powerpc/builtins-3-vec_reve-runnable.c:
diff --git a/gcc/testsuite/g++.dg/Wclass-memaccess-2.C b/gcc/testsuite/g++.dg/Wclass-memaccess-2.C
new file mode 100644 (file)
index 0000000..49581df
--- /dev/null
@@ -0,0 +1,61 @@
+// PR c++/81169 - -Wclass-memaccess illegitimate warning related to volatile
+// { dg-do compile }
+// { dg-options "-Wclass-memaccess" }
+
+struct S { int x; };
+
+void cast_const (const S *p)
+{
+  __builtin_memset (const_cast<S*>(p), 0, sizeof *p);
+}
+
+void cast_volatile (volatile S *p)
+{
+  __builtin_memset (const_cast<S*>(p), 0, sizeof *p);
+}
+
+void cast_const_volatile (const volatile S *p)
+{
+  __builtin_memset (const_cast<S*>(p), 0, sizeof *p);
+}
+
+void c_cast_const_volatile (const volatile S *p)
+{
+  __builtin_memset ((S*)p, 0, sizeof *p);
+}
+
+// A C cast to void* suppresses the warning because it casts away
+// the qualifiers from the otherwise trivial pointed-to type..
+void c_void_cast_const_volatile (const volatile S *p)
+{
+  __builtin_memset ((void*)p, 0, sizeof *p);
+}
+
+// Also verify that casting to char* suppresses the warning for
+// non-trivial types.
+
+struct NonTrivial
+{
+  NonTrivial ();
+  NonTrivial (const NonTrivial&);
+  NonTrivial& operator= (const NonTrivial&);
+  ~NonTrivial ();
+};
+
+void cast_void (NonTrivial *p)
+{
+  __builtin_memset (reinterpret_cast<char*>(p), 0, sizeof *p);
+}
+
+// A C cast to a character (or any trivial) type suppresses the warning.
+void c_cast_uchar (NonTrivial *p)
+{
+  __builtin_memset ((unsigned char*)p, 0, sizeof *p);
+}
+
+// A cast to void* does not suppress the warning.  That is (or can be)
+// considered a feature.
+void c_cast_void (NonTrivial *p)
+{
+  __builtin_memset ((void*)p, 0, sizeof *p);   // { dg-warning "\\\[-Wclass-memaccess]" }
+}