Commit e99ef408 by Jakub Jelinek Committed by Jakub Jelinek

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<tree, va_gc> *, 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
parent 75ce74bb
2018-01-10 Jakub Jelinek <jakub@redhat.com>
PR c++/81327
* call.c (maybe_warn_class_memaccess): Add forward declaration.
Change last argument from tree * to const vec<tree, va_gc> *, 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 <paolo.carlini@oracle.com> 2018-01-10 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/81055 PR c++/81055
......
...@@ -147,6 +147,8 @@ static int equal_functions (tree, tree); ...@@ -147,6 +147,8 @@ static int equal_functions (tree, tree);
static int joust (struct z_candidate *, struct z_candidate *, bool, static int joust (struct z_candidate *, struct z_candidate *, bool,
tsubst_flags_t); tsubst_flags_t);
static int compare_ics (conversion *, conversion *); static int compare_ics (conversion *, conversion *);
static void maybe_warn_class_memaccess (location_t, tree,
const vec<tree, va_gc> *);
static tree build_over_call (struct z_candidate *, int, tsubst_flags_t); static tree build_over_call (struct z_candidate *, int, tsubst_flags_t);
#define convert_like(CONV, EXPR, COMPLAIN) \ #define convert_like(CONV, EXPR, COMPLAIN) \
convert_like_real ((CONV), (EXPR), NULL_TREE, 0, \ 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) ...@@ -8180,6 +8182,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
&& !mark_used (fn, complain)) && !mark_used (fn, complain))
return error_mark_node; 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 if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
/* Don't mess with virtual lookup in instantiate_non_dependent_expr; /* Don't mess with virtual lookup in instantiate_non_dependent_expr;
virtual functions can't be constexpr. */ virtual functions can't be constexpr. */
...@@ -8360,7 +8368,8 @@ has_trivial_copy_p (tree type, bool access, bool hasctor[2]) ...@@ -8360,7 +8368,8 @@ has_trivial_copy_p (tree type, bool access, bool hasctor[2])
assignments. */ assignments. */
static void static void
maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args) maybe_warn_class_memaccess (location_t loc, tree fndecl,
const vec<tree, va_gc> *args)
{ {
/* Except for bcopy where it's second, the destination pointer is /* Except for bcopy where it's second, the destination pointer is
the first argument for all functions handled here. Compute the first argument for all functions handled here. Compute
...@@ -8368,15 +8377,10 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args) ...@@ -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 dstidx = DECL_FUNCTION_CODE (fndecl) == BUILT_IN_BCOPY;
unsigned srcidx = !dstidx; unsigned srcidx = !dstidx;
tree dest = args[dstidx]; tree dest = (*args)[dstidx];
if (!dest || !TREE_TYPE (dest) || !POINTER_TYPE_P (TREE_TYPE (dest))) if (!TREE_TYPE (dest) || !POINTER_TYPE_P (TREE_TYPE (dest)))
return; 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; tree srctype = NULL_TREE;
/* Determine the type of the pointed-to object and whether it's /* 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) ...@@ -8436,7 +8440,7 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args)
switch (DECL_FUNCTION_CODE (fndecl)) switch (DECL_FUNCTION_CODE (fndecl))
{ {
case BUILT_IN_MEMSET: 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, /* Diagnose setting non-copy-assignable or non-trivial types,
or types with a private member, to (potentially) non-zero 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) ...@@ -8497,8 +8501,11 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args)
case BUILT_IN_MEMMOVE: case BUILT_IN_MEMMOVE:
case BUILT_IN_MEMPCPY: case BUILT_IN_MEMPCPY:
/* Determine the type of the source object. */ /* Determine the type of the source object. */
srctype = STRIP_NOPS (args[srcidx]); srctype = TREE_TYPE ((*args)[srcidx]);
srctype = TREE_TYPE (TREE_TYPE (srctype)); 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 /* Since it's impossible to determine wheter the byte copy is
being used in place of assignment to an existing object or 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) ...@@ -8547,13 +8554,16 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args)
"assignment or copy-initialization instead", "assignment or copy-initialization instead",
fndecl, desttype, access, fld, srctype); 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. */ /* Finally, warn on partial copies. */
unsigned HOST_WIDE_INT typesize unsigned HOST_WIDE_INT typesize
= tree_to_uhwi (TYPE_SIZE_UNIT (desttype)); = tree_to_uhwi (TYPE_SIZE_UNIT (desttype));
if (unsigned HOST_WIDE_INT partial if (unsigned HOST_WIDE_INT partial = tree_to_uhwi (sz) % typesize)
= tree_to_uhwi (args[2]) % typesize)
warned = warning_at (loc, OPT_Wclass_memaccess, warned = warning_at (loc, OPT_Wclass_memaccess,
(typesize - partial > 1 (typesize - partial > 1
? G_("%qD writing to an object of " ? G_("%qD writing to an object of "
...@@ -8577,16 +8587,17 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args) ...@@ -8577,16 +8587,17 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args)
else if (!get_dtor (desttype, tf_none)) else if (!get_dtor (desttype, tf_none))
warnfmt = G_("%qD moving an object of type %#qT with deleted " warnfmt = G_("%qD moving an object of type %#qT with deleted "
"destructor"); "destructor");
else if (!trivial else if (!trivial)
&& TREE_CODE (args[1]) == INTEGER_CST
&& tree_int_cst_lt (args[1], TYPE_SIZE_UNIT (desttype)))
{ {
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. */ /* Finally, warn on reallocation into insufficient space. */
warned = warning_at (loc, OPT_Wclass_memaccess, warned = warning_at (loc, OPT_Wclass_memaccess,
"%qD moving an object of non-trivial type " "%qD moving an object of non-trivial type "
"%#qT and size %E into a region of size %E", "%#qT and size %E into a region of size %E",
fndecl, desttype, TYPE_SIZE_UNIT (desttype), fndecl, desttype, TYPE_SIZE_UNIT (desttype),
args[1]); sz);
} }
break; break;
...@@ -8594,9 +8605,6 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args) ...@@ -8594,9 +8605,6 @@ maybe_warn_class_memaccess (location_t loc, tree fndecl, tree *args)
return; return;
} }
if (!warned && !warnfmt)
return;
if (warnfmt) if (warnfmt)
{ {
if (suggest) if (suggest)
...@@ -8643,10 +8651,6 @@ build_cxx_call (tree fn, int nargs, tree *argarray, ...@@ -8643,10 +8651,6 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
if (!check_builtin_function_arguments (EXPR_LOCATION (fn), vNULL, fndecl, if (!check_builtin_function_arguments (EXPR_LOCATION (fn), vNULL, fndecl,
nargs, argarray)) nargs, argarray))
return error_mark_node; 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))) if (VOID_TYPE_P (TREE_TYPE (fn)))
......
2018-01-10 Jakub Jelinek <jakub@redhat.com>
PR c++/81327
* g++.dg/Wclass-memaccess-2.C: Don't expect a warning when explicitly
cast to void *.
2018-01-10 Paolo Carlini <paolo.carlini@oracle.com> 2018-01-10 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/81055 PR c++/81055
......
...@@ -53,9 +53,7 @@ void c_cast_uchar (NonTrivial *p) ...@@ -53,9 +53,7 @@ void c_cast_uchar (NonTrivial *p)
__builtin_memset ((unsigned char*)p, 0, sizeof *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) 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]" }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment