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<tree, va_gc> *);
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, \
&& !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. */
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<tree, va_gc> *args)
{
/* Except for bcopy where it's second, the destination pointer is
the first argument for all functions handled here. Compute
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
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
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
"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 "
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;
return;
}
- if (!warned && !warnfmt)
- return;
-
if (warnfmt)
{
if (suggest)
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)))