From: Jakub Jelinek Date: Wed, 10 Jan 2018 16:59:09 +0000 (+0100) Subject: re PR c++/81327 (cast to void* does not suppress -Wclass-memaccess) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e99ef40892b598eeb3fa496cc472e111675d7f6c;p=gcc.git re PR c++/81327 (cast to void* does not suppress -Wclass-memaccess) PR c++/81327 * call.c (maybe_warn_class_memaccess): Add forward declaration. Change last argument from tree * to const vec *, adjust args uses and check number of operands too. Don't strip away any nops. Use maybe_constant_value when looking for INTEGER_CST args. Deal with src argument not having pointer type. Check tree_fits_uhwi_p before calling tree_to_uhwi. Remove useless test. (build_over_call): Call maybe_warn_class_memaccess here on the original arguments. (build_cxx_call): Rather than here on converted arguments. * g++.dg/Wclass-memaccess-2.C: Don't expect a warning when explicitly cast to void *. From-SVN: r256440 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9b6f4626586..3cce2120b5a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2018-01-10 Jakub Jelinek + + PR c++/81327 + * call.c (maybe_warn_class_memaccess): Add forward declaration. + Change last argument from tree * to const vec *, adjust + args uses and check number of operands too. Don't strip away any + nops. Use maybe_constant_value when looking for INTEGER_CST args. + Deal with src argument not having pointer type. Check + tree_fits_uhwi_p before calling tree_to_uhwi. Remove useless + test. + (build_over_call): Call maybe_warn_class_memaccess here on the + original arguments. + (build_cxx_call): Rather than here on converted arguments. + 2018-01-10 Paolo Carlini PR c++/81055 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 1c54bab124a..515e4607de0 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -147,6 +147,8 @@ static int equal_functions (tree, tree); static int joust (struct z_candidate *, struct z_candidate *, bool, tsubst_flags_t); static int compare_ics (conversion *, conversion *); +static void maybe_warn_class_memaccess (location_t, tree, + const vec *); static tree build_over_call (struct z_candidate *, int, tsubst_flags_t); #define convert_like(CONV, EXPR, COMPLAIN) \ convert_like_real ((CONV), (EXPR), NULL_TREE, 0, \ @@ -8180,6 +8182,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) && !mark_used (fn, complain)) return error_mark_node; + /* Warn if the built-in writes to an object of a non-trivial type. */ + if (warn_class_memaccess + && vec_safe_length (args) >= 2 + && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL) + maybe_warn_class_memaccess (input_location, fn, args); + if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0 /* Don't mess with virtual lookup in instantiate_non_dependent_expr; virtual functions can't be constexpr. */ @@ -8360,7 +8368,8 @@ has_trivial_copy_p (tree type, bool access, bool hasctor[2]) assignments. */ static void -maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args) +maybe_warn_class_memaccess (location_t loc, tree fndecl, + const vec *args) { /* Except for bcopy where it's second, the destination pointer is the first argument for all functions handled here. Compute @@ -8368,15 +8377,10 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args) unsigned dstidx = DECL_FUNCTION_CODE (fndecl) == BUILT_IN_BCOPY; unsigned srcidx = !dstidx; - tree dest = args[dstidx]; - if (!dest || !TREE_TYPE (dest) || !POINTER_TYPE_P (TREE_TYPE (dest))) + tree dest = (*args)[dstidx]; + if (!TREE_TYPE (dest) || !POINTER_TYPE_P (TREE_TYPE (dest))) return; - /* 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; /* Determine the type of the pointed-to object and whether it's @@ -8436,7 +8440,7 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args) switch (DECL_FUNCTION_CODE (fndecl)) { case BUILT_IN_MEMSET: - if (!integer_zerop (args[1])) + if (!integer_zerop (maybe_constant_value ((*args)[1]))) { /* Diagnose setting non-copy-assignable or non-trivial types, or types with a private member, to (potentially) non-zero @@ -8497,8 +8501,11 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args) case BUILT_IN_MEMMOVE: case BUILT_IN_MEMPCPY: /* Determine the type of the source object. */ - srctype = STRIP_NOPS (args[srcidx]); - srctype = TREE_TYPE (TREE_TYPE (srctype)); + srctype = TREE_TYPE ((*args)[srcidx]); + if (!srctype || !POINTER_TYPE_P (srctype)) + srctype = void_type_node; + else + srctype = TREE_TYPE (srctype); /* Since it's impossible to determine wheter the byte copy is being used in place of assignment to an existing object or @@ -8547,13 +8554,16 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args) "assignment or copy-initialization instead", fndecl, desttype, access, fld, srctype); } - else if (!trivial && TREE_CODE (args[2]) == INTEGER_CST) + else if (!trivial && vec_safe_length (args) > 2) { + tree sz = maybe_constant_value ((*args)[2]); + if (!tree_fits_uhwi_p (sz)) + break; + /* Finally, warn on partial copies. */ unsigned HOST_WIDE_INT typesize = tree_to_uhwi (TYPE_SIZE_UNIT (desttype)); - if (unsigned HOST_WIDE_INT partial - = tree_to_uhwi (args[2]) % typesize) + if (unsigned HOST_WIDE_INT partial = tree_to_uhwi (sz) % typesize) warned = warning_at (loc, OPT_Wclass_memaccess, (typesize - partial > 1 ? G_("%qD writing to an object of " @@ -8577,16 +8587,17 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args) else if (!get_dtor (desttype, tf_none)) warnfmt = G_("%qD moving an object of type %#qT with deleted " "destructor"); - else if (!trivial - && TREE_CODE (args[1]) == INTEGER_CST - && tree_int_cst_lt (args[1], TYPE_SIZE_UNIT (desttype))) + else if (!trivial) { - /* Finally, warn on reallocation into insufficient space. */ - warned = warning_at (loc, OPT_Wclass_memaccess, - "%qD moving an object of non-trivial type " - "%#qT and size %E into a region of size %E", - fndecl, desttype, TYPE_SIZE_UNIT (desttype), - args[1]); + tree sz = maybe_constant_value ((*args)[1]); + if (TREE_CODE (sz) == INTEGER_CST + && tree_int_cst_lt (sz, TYPE_SIZE_UNIT (desttype))) + /* Finally, warn on reallocation into insufficient space. */ + warned = warning_at (loc, OPT_Wclass_memaccess, + "%qD moving an object of non-trivial type " + "%#qT and size %E into a region of size %E", + fndecl, desttype, TYPE_SIZE_UNIT (desttype), + sz); } break; @@ -8594,9 +8605,6 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args) return; } - if (!warned && !warnfmt) - return; - if (warnfmt) { if (suggest) @@ -8643,10 +8651,6 @@ build_cxx_call (tree fn, int nargs, tree *argarray, if (!check_builtin_function_arguments (EXPR_LOCATION (fn), vNULL, fndecl, nargs, argarray)) return error_mark_node; - - /* Warn if the built-in writes to an object of a non-trivial type. */ - if (nargs) - maybe_warn_class_memaccess (loc, fndecl, argarray); } if (VOID_TYPE_P (TREE_TYPE (fn))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dca24d8f28b..0bfacf0d0e6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-01-10 Jakub Jelinek + + PR c++/81327 + * g++.dg/Wclass-memaccess-2.C: Don't expect a warning when explicitly + cast to void *. + 2018-01-10 Paolo Carlini PR c++/81055 diff --git a/gcc/testsuite/g++.dg/Wclass-memaccess-2.C b/gcc/testsuite/g++.dg/Wclass-memaccess-2.C index 49581df1204..f138b8b357e 100644 --- a/gcc/testsuite/g++.dg/Wclass-memaccess-2.C +++ b/gcc/testsuite/g++.dg/Wclass-memaccess-2.C @@ -53,9 +53,7 @@ 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]" } + __builtin_memset ((void*)p, 0, sizeof *p); // { dg-bogus "\\\[-Wclass-memaccess]" } }