diff options
author | Martin Sebor <msebor@redhat.com> | 2017-06-26 17:19:15 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2017-06-26 11:19:15 -0600 |
commit | 4b377e01ce6b56e0ec0276596e47bfbaacf97aa6 (patch) | |
tree | f40e76f1d3078a7edf198e4176f6e27220c875c4 | |
parent | b269e8998d5cc47d010d915aba548fa0ae2d8bf8 (diff) | |
download | gcc-4b377e01ce6b56e0ec0276596e47bfbaacf97aa6.zip gcc-4b377e01ce6b56e0ec0276596e47bfbaacf97aa6.tar.gz gcc-4b377e01ce6b56e0ec0276596e47bfbaacf97aa6.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/call.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/Wclass-memaccess-2.C | 61 |
4 files changed, 77 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 040f7b7..8bc268c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f480611..ff0a26b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8b1d5af..d7c906a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..49581df --- /dev/null +++ b/gcc/testsuite/g++.dg/Wclass-memaccess-2.C @@ -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]" } +} |