PR c++/81169 - -Wclass-memaccess illegitimate warning related to volatile

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
This commit is contained in:
Martin Sebor 2017-06-26 17:19:15 +00:00 committed by Martin Sebor
parent b269e8998d
commit 4b377e01ce
4 changed files with 77 additions and 2 deletions

View 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.

View 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);

View 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:

View file

@ -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]" }
}