Correct handling of variable offset minus constant in -Warray-bounds [PR100137]
Resolves: PR tree-optimization/100137 - -Warray-bounds false positive on varying offset plus negative PR tree-optimization/99121 - ICE in -Warray-bounds on a multidimensional PR tree-optimization/97027 - missing warning on buffer overflow storing a larger scalar into a smaller array gcc/ChangeLog: PR tree-optimization/100137 PR tree-optimization/99121 PR tree-optimization/97027 * builtins.c (access_ref::access_ref): Also set offmax. (access_ref::offset_in_range): Define new function. (access_ref::add_offset): Set offmax. (access_ref::inform_access): Handle access_none. (handle_mem_ref): Clear ostype. (compute_objsize_r): Handle ASSERT_EXPR. * builtins.h (struct access_ref): Add offmax member. * gimple-array-bounds.cc (array_bounds_checker::check_mem_ref): Use compute_objsize() and simplify. gcc/testsuite/ChangeLog: PR tree-optimization/100137 PR tree-optimization/99121 PR tree-optimization/97027 * c-c++-common/Warray-bounds-3.c: Remove xfail * c-c++-common/Warray-bounds-4.c: Add an expected warning. * c-c++-common/Warray-bounds-9.c: New test. * c-c++-common/Warray-bounds-10.c: New test. * g++.dg/asan/asan_test.C: Suppress expected warnings. * g++.dg/pr95768.C: Same. * g++.dg/warn/Warray-bounds-10.C: Adjust text of expected messages. * g++.dg/warn/Warray-bounds-11.C: Same. * g++.dg/warn/Warray-bounds-12.C: Same. * g++.dg/warn/Warray-bounds-13.C: Same. * g++.dg/warn/Warray-bounds-17.C: Same. * g++.dg/warn/Warray-bounds-20.C: Same. * gcc.dg/Warray-bounds-29.c: Same. * gcc.dg/Warray-bounds-30.c: Add xfail. * gcc.dg/Warray-bounds-31.c: Adjust text of expected messages. * gcc.dg/Warray-bounds-32.c: Same. * gcc.dg/Warray-bounds-52.c: Same. * gcc.dg/Warray-bounds-53.c: Same. * gcc.dg/Warray-bounds-58.c: Remove xfail. * gcc.dg/Warray-bounds-63.c: Adjust text of expected messages. * gcc.dg/Warray-bounds-66.c: Same. * gcc.dg/Warray-bounds-69.c: Same. * gcc.dg/Wstringop-overflow-34.c: Same. * gcc.dg/Wstringop-overflow-47.c: Same. * gcc.dg/Wstringop-overflow-61.c: Same. * gcc.dg/Warray-bounds-77.c: New test. * gcc.dg/Warray-bounds-78.c: New test. * gcc.dg/Warray-bounds-79.c: New test.
This commit is contained in:
parent
6278065af0
commit
a110855667
31 changed files with 829 additions and 383 deletions
|
@ -206,6 +206,7 @@ access_ref::access_ref (tree bound /* = NULL_TREE */,
|
|||
{
|
||||
/* Set to valid. */
|
||||
offrng[0] = offrng[1] = 0;
|
||||
offmax[0] = offmax[1] = 0;
|
||||
/* Invalidate. */
|
||||
sizrng[0] = sizrng[1] = -1;
|
||||
|
||||
|
@ -457,6 +458,21 @@ access_ref::size_remaining (offset_int *pmin /* = NULL */) const
|
|||
return sizrng[1] - or0;
|
||||
}
|
||||
|
||||
/* Return true if the offset and object size are in range for SIZE. */
|
||||
|
||||
bool
|
||||
access_ref::offset_in_range (const offset_int &size) const
|
||||
{
|
||||
if (size_remaining () < size)
|
||||
return false;
|
||||
|
||||
if (base0)
|
||||
return offmax[0] >= 0 && offmax[1] <= sizrng[1];
|
||||
|
||||
offset_int maxoff = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
|
||||
return offmax[0] > -maxoff && offmax[1] < maxoff;
|
||||
}
|
||||
|
||||
/* Add the range [MIN, MAX] to the offset range. For known objects (with
|
||||
zero-based offsets) at least one of whose offset's bounds is in range,
|
||||
constrain the other (or both) to the bounds of the object (i.e., zero
|
||||
|
@ -493,6 +509,8 @@ void access_ref::add_offset (const offset_int &min, const offset_int &max)
|
|||
if (max >= 0)
|
||||
{
|
||||
offrng[0] = 0;
|
||||
if (offmax[0] > 0)
|
||||
offmax[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -509,6 +527,12 @@ void access_ref::add_offset (const offset_int &min, const offset_int &max)
|
|||
offrng[0] = 0;
|
||||
}
|
||||
|
||||
/* Set the minimum and maximmum computed so far. */
|
||||
if (offrng[1] < 0 && offrng[1] < offmax[0])
|
||||
offmax[0] = offrng[1];
|
||||
if (offrng[0] > 0 && offrng[0] > offmax[1])
|
||||
offmax[1] = offrng[0];
|
||||
|
||||
if (!base0)
|
||||
return;
|
||||
|
||||
|
@ -4571,23 +4595,46 @@ access_ref::inform_access (access_mode mode) const
|
|||
return;
|
||||
}
|
||||
|
||||
if (mode == access_read_only)
|
||||
{
|
||||
if (allocfn == NULL_TREE)
|
||||
{
|
||||
if (*offstr)
|
||||
inform (loc, "at offset %s into source object %qE of size %s",
|
||||
offstr, ref, sizestr);
|
||||
else
|
||||
inform (loc, "source object %qE of size %s", ref, sizestr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (*offstr)
|
||||
inform (loc,
|
||||
"at offset %s into source object of size %s allocated by %qE",
|
||||
offstr, sizestr, allocfn);
|
||||
else
|
||||
inform (loc, "source object of size %s allocated by %qE",
|
||||
sizestr, allocfn);
|
||||
return;
|
||||
}
|
||||
|
||||
if (allocfn == NULL_TREE)
|
||||
{
|
||||
if (*offstr)
|
||||
inform (loc, "at offset %s into source object %qE of size %s",
|
||||
inform (loc, "at offset %s into object %qE of size %s",
|
||||
offstr, ref, sizestr);
|
||||
else
|
||||
inform (loc, "source object %qE of size %s", ref, sizestr);
|
||||
inform (loc, "object %qE of size %s", ref, sizestr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (*offstr)
|
||||
inform (loc,
|
||||
"at offset %s into source object of size %s allocated by %qE",
|
||||
"at offset %s into object of size %s allocated by %qE",
|
||||
offstr, sizestr, allocfn);
|
||||
else
|
||||
inform (loc, "source object of size %s allocated by %qE",
|
||||
inform (loc, "object of size %s allocated by %qE",
|
||||
sizestr, allocfn);
|
||||
}
|
||||
|
||||
|
@ -5433,16 +5480,16 @@ handle_mem_ref (tree mref, int ostype, access_ref *pref,
|
|||
|
||||
if (VECTOR_TYPE_P (TREE_TYPE (mref)))
|
||||
{
|
||||
/* Hack: Give up for MEM_REFs of vector types; those may be
|
||||
synthesized from multiple assignments to consecutive data
|
||||
members (see PR 93200 and 96963).
|
||||
/* Hack: Handle MEM_REFs of vector types as those to complete
|
||||
objects; those may be synthesized from multiple assignments
|
||||
to consecutive data members (see PR 93200 and 96963).
|
||||
FIXME: Vectorized assignments should only be present after
|
||||
vectorization so this hack is only necessary after it has
|
||||
run and could be avoided in calls from prior passes (e.g.,
|
||||
tree-ssa-strlen.c).
|
||||
FIXME: Deal with this more generally, e.g., by marking up
|
||||
such MEM_REFs at the time they're created. */
|
||||
return false;
|
||||
ostype = 0;
|
||||
}
|
||||
|
||||
tree mrefop = TREE_OPERAND (mref, 0);
|
||||
|
@ -5796,6 +5843,12 @@ compute_objsize_r (tree ptr, int ostype, access_ref *pref,
|
|||
|
||||
tree rhs = gimple_assign_rhs1 (stmt);
|
||||
|
||||
if (code == ASSERT_EXPR)
|
||||
{
|
||||
rhs = TREE_OPERAND (rhs, 0);
|
||||
return compute_objsize_r (rhs, ostype, pref, snlim, qry);
|
||||
}
|
||||
|
||||
if (code == POINTER_PLUS_EXPR
|
||||
&& TREE_CODE (TREE_TYPE (rhs)) == POINTER_TYPE)
|
||||
{
|
||||
|
|
|
@ -222,6 +222,9 @@ struct access_ref
|
|||
argument to the minimum. */
|
||||
offset_int size_remaining (offset_int * = NULL) const;
|
||||
|
||||
/* Return true if the offset and object size are in range for SIZE. */
|
||||
bool offset_in_range (const offset_int &) const;
|
||||
|
||||
/* Return true if *THIS is an access to a declared object. */
|
||||
bool ref_declared () const
|
||||
{
|
||||
|
@ -261,6 +264,8 @@ struct access_ref
|
|||
/* Range of byte offsets into and sizes of the object(s). */
|
||||
offset_int offrng[2];
|
||||
offset_int sizrng[2];
|
||||
/* The minimum and maximum offset computed. */
|
||||
offset_int offmax[2];
|
||||
/* Range of the bound of the access: denotes that the access
|
||||
is at least BNDRNG[0] bytes but no more than BNDRNG[1].
|
||||
For string functions the size of the actual access is
|
||||
|
|
|
@ -414,262 +414,11 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
|
|||
if (warning_suppressed_p (ref, OPT_Warray_bounds))
|
||||
return false;
|
||||
|
||||
tree arg = TREE_OPERAND (ref, 0);
|
||||
/* The constant and variable offset of the reference. */
|
||||
tree cstoff = TREE_OPERAND (ref, 1);
|
||||
tree varoff = NULL_TREE;
|
||||
|
||||
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
|
||||
|
||||
/* The zero-based array or string constant bounds in bytes. Initially
|
||||
set to [-MAXOBJSIZE - 1, MAXOBJSIZE] until a tighter bound is
|
||||
determined. */
|
||||
offset_int arrbounds[2] = { -maxobjsize - 1, maxobjsize };
|
||||
|
||||
/* The minimum and maximum intermediate offset. For a reference
|
||||
to be valid, not only does the final offset/subscript must be
|
||||
in bounds but all intermediate offsets should be as well.
|
||||
GCC may be able to deal gracefully with such out-of-bounds
|
||||
offsets so the checking is only enabled at -Warray-bounds=2
|
||||
where it may help detect bugs in uses of the intermediate
|
||||
offsets that could otherwise not be detectable. */
|
||||
offset_int ioff = wi::to_offset (fold_convert (ptrdiff_type_node, cstoff));
|
||||
offset_int extrema[2] = { 0, wi::abs (ioff) };
|
||||
|
||||
/* The range of the byte offset into the reference. */
|
||||
offset_int offrange[2] = { 0, 0 };
|
||||
|
||||
/* The statement used to allocate the array or null. */
|
||||
gimple *alloc_stmt = NULL;
|
||||
/* For an allocation statement, the low bound of the size range. */
|
||||
offset_int minbound = 0;
|
||||
|
||||
/* Determine the offsets and increment OFFRANGE for the bounds of each.
|
||||
The loop computes the range of the final offset for expressions such
|
||||
as (A + i0 + ... + iN)[CSTOFF] where i0 through iN are SSA_NAMEs in
|
||||
some range. */
|
||||
const unsigned limit = param_ssa_name_def_chain_limit;
|
||||
for (unsigned n = 0; TREE_CODE (arg) == SSA_NAME && n < limit; ++n)
|
||||
{
|
||||
gimple *def = SSA_NAME_DEF_STMT (arg);
|
||||
if (is_gimple_call (def))
|
||||
{
|
||||
/* Determine the byte size of the array from an allocation call. */
|
||||
wide_int sizrng[2];
|
||||
if (gimple_call_alloc_size (def, sizrng))
|
||||
{
|
||||
arrbounds[0] = 0;
|
||||
arrbounds[1] = offset_int::from (sizrng[1], UNSIGNED);
|
||||
minbound = offset_int::from (sizrng[0], UNSIGNED);
|
||||
alloc_stmt = def;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (gimple_nop_p (def))
|
||||
{
|
||||
/* For a function argument try to determine the byte size
|
||||
of the array from the current function declaratation
|
||||
(e.g., attribute access or related). */
|
||||
wide_int wr[2];
|
||||
tree ref = gimple_parm_array_size (arg, wr);
|
||||
if (!ref)
|
||||
break;
|
||||
arrbounds[0] = offset_int::from (wr[0], UNSIGNED);
|
||||
arrbounds[1] = offset_int::from (wr[1], UNSIGNED);
|
||||
arg = ref;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_gimple_assign (def))
|
||||
break;
|
||||
|
||||
tree_code code = gimple_assign_rhs_code (def);
|
||||
if (code == POINTER_PLUS_EXPR)
|
||||
{
|
||||
arg = gimple_assign_rhs1 (def);
|
||||
varoff = gimple_assign_rhs2 (def);
|
||||
}
|
||||
else if (code == ASSERT_EXPR)
|
||||
{
|
||||
arg = TREE_OPERAND (gimple_assign_rhs1 (def), 0);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
/* VAROFF should always be a SSA_NAME here (and not even
|
||||
INTEGER_CST) but there's no point in taking chances. */
|
||||
if (TREE_CODE (varoff) != SSA_NAME)
|
||||
break;
|
||||
|
||||
const value_range* const vr = get_value_range (varoff);
|
||||
if (!vr || vr->undefined_p () || vr->varying_p ())
|
||||
break;
|
||||
|
||||
if (!vr->constant_p ())
|
||||
break;
|
||||
|
||||
if (vr->kind () == VR_RANGE)
|
||||
{
|
||||
offset_int min
|
||||
= wi::to_offset (fold_convert (ptrdiff_type_node, vr->min ()));
|
||||
offset_int max
|
||||
= wi::to_offset (fold_convert (ptrdiff_type_node, vr->max ()));
|
||||
if (min < max)
|
||||
{
|
||||
offrange[0] += min;
|
||||
offrange[1] += max;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* When MIN >= MAX, the offset is effectively in a union
|
||||
of two ranges: [-MAXOBJSIZE -1, MAX] and [MIN, MAXOBJSIZE].
|
||||
Since there is no way to represent such a range across
|
||||
additions, conservatively add [-MAXOBJSIZE -1, MAXOBJSIZE]
|
||||
to OFFRANGE. */
|
||||
offrange[0] += arrbounds[0];
|
||||
offrange[1] += arrbounds[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For an anti-range, analogously to the above, conservatively
|
||||
add [-MAXOBJSIZE -1, MAXOBJSIZE] to OFFRANGE. */
|
||||
offrange[0] += arrbounds[0];
|
||||
offrange[1] += arrbounds[1];
|
||||
}
|
||||
|
||||
/* Keep track of the minimum and maximum offset. */
|
||||
if (offrange[1] < 0 && offrange[1] < extrema[0])
|
||||
extrema[0] = offrange[1];
|
||||
if (offrange[0] > 0 && offrange[0] > extrema[1])
|
||||
extrema[1] = offrange[0];
|
||||
|
||||
if (offrange[0] < arrbounds[0])
|
||||
offrange[0] = arrbounds[0];
|
||||
|
||||
if (offrange[1] > arrbounds[1])
|
||||
offrange[1] = arrbounds[1];
|
||||
}
|
||||
|
||||
tree reftype = NULL_TREE;
|
||||
offset_int eltsize = -1;
|
||||
if (arrbounds[0] >= 0)
|
||||
{
|
||||
/* The byte size of the array has already been determined above
|
||||
based on a pointer ARG. Set ELTSIZE to the size of the type
|
||||
it points to and REFTYPE to the array with the size, rounded
|
||||
down as necessary. */
|
||||
reftype = TREE_TYPE (TREE_TYPE (arg));
|
||||
if (TREE_CODE (reftype) == ARRAY_TYPE)
|
||||
reftype = TREE_TYPE (reftype);
|
||||
if (tree refsize = TYPE_SIZE_UNIT (reftype))
|
||||
if (TREE_CODE (refsize) == INTEGER_CST)
|
||||
eltsize = wi::to_offset (refsize);
|
||||
|
||||
if (eltsize < 0)
|
||||
return false;
|
||||
|
||||
offset_int nelts = arrbounds[1] / eltsize;
|
||||
reftype = build_printable_array_type (reftype, nelts.to_uhwi ());
|
||||
}
|
||||
else if (TREE_CODE (arg) == ADDR_EXPR)
|
||||
{
|
||||
arg = TREE_OPERAND (arg, 0);
|
||||
if (TREE_CODE (arg) != STRING_CST
|
||||
&& TREE_CODE (arg) != PARM_DECL
|
||||
&& TREE_CODE (arg) != VAR_DECL)
|
||||
return false;
|
||||
|
||||
/* The type of the object being referred to. It can be an array,
|
||||
string literal, or a non-array type when the MEM_REF represents
|
||||
a reference/subscript via a pointer to an object that is not
|
||||
an element of an array. Incomplete types are excluded as well
|
||||
because their size is not known. */
|
||||
reftype = TREE_TYPE (arg);
|
||||
if (POINTER_TYPE_P (reftype)
|
||||
|| !COMPLETE_TYPE_P (reftype)
|
||||
|| TREE_CODE (TYPE_SIZE_UNIT (reftype)) != INTEGER_CST)
|
||||
return false;
|
||||
|
||||
/* Except in declared objects, references to trailing array members
|
||||
of structs and union objects are excluded because MEM_REF doesn't
|
||||
make it possible to identify the member where the reference
|
||||
originated. */
|
||||
if (RECORD_OR_UNION_TYPE_P (reftype)
|
||||
&& (!VAR_P (arg)
|
||||
|| (DECL_EXTERNAL (arg) && array_at_struct_end_p (ref))))
|
||||
return false;
|
||||
|
||||
/* FIXME: Should this be 1 for Fortran? */
|
||||
arrbounds[0] = 0;
|
||||
|
||||
if (TREE_CODE (reftype) == ARRAY_TYPE)
|
||||
{
|
||||
/* Set to the size of the array element (and adjust below). */
|
||||
eltsize = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (reftype)));
|
||||
/* Use log2 of size to convert the array byte size in to its
|
||||
upper bound in elements. */
|
||||
const offset_int eltsizelog2 = wi::floor_log2 (eltsize);
|
||||
if (tree dom = TYPE_DOMAIN (reftype))
|
||||
{
|
||||
tree bnds[] = { TYPE_MIN_VALUE (dom), TYPE_MAX_VALUE (dom) };
|
||||
if (TREE_CODE (arg) == COMPONENT_REF)
|
||||
{
|
||||
offset_int size = maxobjsize;
|
||||
if (tree fldsize = component_ref_size (arg))
|
||||
size = wi::to_offset (fldsize);
|
||||
arrbounds[1] = wi::lrshift (size, eltsizelog2);
|
||||
}
|
||||
else if (array_at_struct_end_p (arg) || !bnds[0] || !bnds[1])
|
||||
arrbounds[1] = wi::lrshift (maxobjsize, eltsizelog2);
|
||||
else
|
||||
arrbounds[1] = (wi::to_offset (bnds[1]) - wi::to_offset (bnds[0])
|
||||
+ 1) * eltsize;
|
||||
}
|
||||
else
|
||||
arrbounds[1] = wi::lrshift (maxobjsize, eltsizelog2);
|
||||
|
||||
/* Determine a tighter bound of the non-array element type. */
|
||||
tree eltype = TREE_TYPE (reftype);
|
||||
while (TREE_CODE (eltype) == ARRAY_TYPE)
|
||||
eltype = TREE_TYPE (eltype);
|
||||
eltsize = wi::to_offset (TYPE_SIZE_UNIT (eltype));
|
||||
}
|
||||
else
|
||||
{
|
||||
eltsize = 1;
|
||||
tree size = TYPE_SIZE_UNIT (reftype);
|
||||
if (VAR_P (arg))
|
||||
if (tree initsize = DECL_SIZE_UNIT (arg))
|
||||
if (tree_int_cst_lt (size, initsize))
|
||||
size = initsize;
|
||||
|
||||
arrbounds[1] = wi::to_offset (size);
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
offrange[0] += ioff;
|
||||
offrange[1] += ioff;
|
||||
|
||||
/* Compute the more permissive upper bound when IGNORE_OFF_BY_ONE
|
||||
is set (when taking the address of the one-past-last element
|
||||
of an array) but always use the stricter bound in diagnostics. */
|
||||
offset_int ubound = arrbounds[1];
|
||||
if (ignore_off_by_one)
|
||||
ubound += eltsize;
|
||||
|
||||
bool warned = false;
|
||||
/* Set if the lower bound of the subscript is out of bounds. */
|
||||
const bool lboob = (arrbounds[0] == arrbounds[1]
|
||||
|| offrange[0] >= ubound
|
||||
|| offrange[1] < arrbounds[0]);
|
||||
/* Set if only the upper bound of the subscript is out of bounds.
|
||||
This can happen when using a bigger type to index into an array
|
||||
of a smaller type, as is common with unsigned char. */
|
||||
/* The type and size of the access. */
|
||||
tree axstype = TREE_TYPE (ref);
|
||||
offset_int axssize = 0;
|
||||
if (TREE_CODE (axstype) != UNION_TYPE)
|
||||
|
@ -677,6 +426,60 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
|
|||
if (TREE_CODE (access_size) == INTEGER_CST)
|
||||
axssize = wi::to_offset (access_size);
|
||||
|
||||
access_ref aref;
|
||||
if (!compute_objsize (ref, 1, &aref, ranges))
|
||||
return false;
|
||||
|
||||
if (aref.offset_in_range (axssize))
|
||||
return false;
|
||||
|
||||
if (TREE_CODE (aref.ref) == SSA_NAME)
|
||||
{
|
||||
gimple *def = SSA_NAME_DEF_STMT (aref.ref);
|
||||
if (is_gimple_call (def))
|
||||
{
|
||||
/* Save the allocation call and the low bound on the size. */
|
||||
alloc_stmt = def;
|
||||
minbound = aref.sizrng[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* The range of the byte offset into the reference. Adjusted below. */
|
||||
offset_int offrange[2] = { aref.offrng[0], aref.offrng[1] };
|
||||
|
||||
/* The type of the referenced object. */
|
||||
tree reftype = TREE_TYPE (aref.ref);
|
||||
/* The size of the referenced array element. */
|
||||
offset_int eltsize = 1;
|
||||
/* The byte size of the array has already been determined above
|
||||
based on a pointer ARG. Set ELTSIZE to the size of the type
|
||||
it points to and REFTYPE to the array with the size, rounded
|
||||
down as necessary. */
|
||||
if (POINTER_TYPE_P (reftype))
|
||||
reftype = TREE_TYPE (reftype);
|
||||
if (TREE_CODE (reftype) == ARRAY_TYPE)
|
||||
reftype = TREE_TYPE (reftype);
|
||||
if (tree refsize = TYPE_SIZE_UNIT (reftype))
|
||||
if (TREE_CODE (refsize) == INTEGER_CST)
|
||||
eltsize = wi::to_offset (refsize);
|
||||
|
||||
const offset_int nelts = aref.sizrng[1] / eltsize;
|
||||
reftype = build_printable_array_type (reftype, nelts.to_uhwi ());
|
||||
|
||||
/* Compute the more permissive upper bound when IGNORE_OFF_BY_ONE
|
||||
is set (when taking the address of the one-past-last element
|
||||
of an array) but always use the stricter bound in diagnostics. */
|
||||
offset_int ubound = aref.sizrng[1];
|
||||
if (ignore_off_by_one)
|
||||
ubound += eltsize;
|
||||
|
||||
/* Set if the lower bound of the subscript is out of bounds. */
|
||||
const bool lboob = (aref.sizrng[1] == 0
|
||||
|| offrange[0] >= ubound
|
||||
|| offrange[1] < 0);
|
||||
/* Set if only the upper bound of the subscript is out of bounds.
|
||||
This can happen when using a bigger type to index into an array
|
||||
of a smaller type, as is common with unsigned char. */
|
||||
const bool uboob = !lboob && offrange[0] + axssize > ubound;
|
||||
if (lboob || uboob)
|
||||
{
|
||||
|
@ -689,9 +492,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
|
|||
to compute the index to print in the diagnostic; arrays
|
||||
in MEM_REF don't mean anything. A type with no size like
|
||||
void is as good as having a size of 1. */
|
||||
tree type = TREE_TYPE (ref);
|
||||
while (TREE_CODE (type) == ARRAY_TYPE)
|
||||
type = TREE_TYPE (type);
|
||||
tree type = strip_array_types (TREE_TYPE (ref));
|
||||
if (tree size = TYPE_SIZE_UNIT (type))
|
||||
{
|
||||
offrange[0] = offrange[0] / wi::to_offset (size);
|
||||
|
@ -699,6 +500,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
|
|||
}
|
||||
}
|
||||
|
||||
bool warned = false;
|
||||
if (lboob)
|
||||
{
|
||||
if (offrange[0] == offrange[1])
|
||||
|
@ -720,7 +522,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
|
|||
/* If the memory was dynamically allocated refer to it as if
|
||||
it were an untyped array of bytes. */
|
||||
backtype = build_array_type_nelts (unsigned_char_type_node,
|
||||
arrbounds[1].to_uhwi ());
|
||||
aref.sizrng[1].to_uhwi ());
|
||||
|
||||
warned = warning_at (location, OPT_Warray_bounds,
|
||||
"array subscript %<%T[%wi]%> is partly "
|
||||
|
@ -730,46 +532,8 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
|
|||
|
||||
if (warned)
|
||||
{
|
||||
if (DECL_P (arg))
|
||||
inform (DECL_SOURCE_LOCATION (arg), "while referencing %qD", arg);
|
||||
else if (alloc_stmt)
|
||||
{
|
||||
location_t loc = gimple_location (alloc_stmt);
|
||||
if (gimple_call_builtin_p (alloc_stmt, BUILT_IN_ALLOCA_WITH_ALIGN))
|
||||
{
|
||||
if (minbound == arrbounds[1])
|
||||
inform (loc, "referencing a variable length array "
|
||||
"of size %wu", minbound.to_uhwi ());
|
||||
else
|
||||
inform (loc, "referencing a variable length array "
|
||||
"of size between %wu and %wu",
|
||||
minbound.to_uhwi (), arrbounds[1].to_uhwi ());
|
||||
}
|
||||
else if (tree fndecl = gimple_call_fndecl (alloc_stmt))
|
||||
{
|
||||
if (minbound == arrbounds[1])
|
||||
inform (loc, "referencing an object of size %wu "
|
||||
"allocated by %qD",
|
||||
minbound.to_uhwi (), fndecl);
|
||||
else
|
||||
inform (loc, "referencing an object of size between "
|
||||
"%wu and %wu allocated by %qD",
|
||||
minbound.to_uhwi (), arrbounds[1].to_uhwi (), fndecl);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree fntype = gimple_call_fntype (alloc_stmt);
|
||||
if (minbound == arrbounds[1])
|
||||
inform (loc, "referencing an object of size %wu "
|
||||
"allocated by %qT",
|
||||
minbound.to_uhwi (), fntype);
|
||||
else
|
||||
inform (loc, "referencing an object of size between "
|
||||
"%wu and %wu allocated by %qT",
|
||||
minbound.to_uhwi (), arrbounds[1].to_uhwi (), fntype);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Determine the access from the statement and use it. */
|
||||
aref.inform_access (access_none);
|
||||
suppress_warning (ref, OPT_Warray_bounds);
|
||||
return true;
|
||||
}
|
||||
|
@ -779,9 +543,9 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref,
|
|||
|
||||
/* At level 2 check also intermediate offsets. */
|
||||
int i = 0;
|
||||
if (extrema[i] < -arrbounds[1] || extrema[i = 1] > ubound)
|
||||
if (aref.offmax[i] < -aref.sizrng[1] || aref.offmax[i = 1] > ubound)
|
||||
{
|
||||
HOST_WIDE_INT tmpidx = extrema[i].to_shwi () / eltsize.to_shwi ();
|
||||
HOST_WIDE_INT tmpidx = aref.offmax[i].to_shwi () / eltsize.to_shwi ();
|
||||
|
||||
if (warning_at (location, OPT_Warray_bounds,
|
||||
"intermediate array offset %wi is outside array bounds "
|
||||
|
|
114
gcc/testsuite/c-c++-common/Warray-bounds-10.c
Normal file
114
gcc/testsuite/c-c++-common/Warray-bounds-10.c
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* PR tree-optimization/99475 - bogus -Warray-bounds accessing an array
|
||||
element of empty structs
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wall" } */
|
||||
|
||||
struct S
|
||||
{
|
||||
#if SOME_CONFIG_MACRO
|
||||
/* Suppose the contents are empty in the development configuration
|
||||
but non-empty in others. Out of bounds accesses to elements of
|
||||
the arrays below should be diagnosed in all configurations,
|
||||
including when S is empty, even if they are folded away. */
|
||||
int member;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct S sa3[3];
|
||||
extern struct S sa2_3[2][3];
|
||||
extern struct S sa3_4_5[3][4][5];
|
||||
|
||||
void sink (void*);
|
||||
|
||||
|
||||
void access_sa3 (struct S s)
|
||||
{
|
||||
sa3[0] = s;
|
||||
sa3[1] = s;
|
||||
sa3[2] = s;
|
||||
sa3[3] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
}
|
||||
|
||||
void access_sa3_ptr (struct S s)
|
||||
{
|
||||
struct S *p = &sa3[0];
|
||||
|
||||
p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[3] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
}
|
||||
|
||||
void access_sa2_3_ptr (struct S s)
|
||||
{
|
||||
struct S *p = &sa2_3[0][0];
|
||||
|
||||
p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[6] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
}
|
||||
|
||||
void access_sa3_4_5_ptr (struct S s, int i)
|
||||
{
|
||||
struct S *p = &sa3_4_5[0][0][0];
|
||||
|
||||
p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[60] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
}
|
||||
|
||||
|
||||
void access_vla3 (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla3[3 < n ? 3 : n];
|
||||
|
||||
vla3[0] = s;
|
||||
vla3[1] = s;
|
||||
vla3[2] = s;
|
||||
vla3[3] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
|
||||
sink (vla3);
|
||||
}
|
||||
|
||||
void access_vla3_ptr (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla3[3 < n ? 3 : n];
|
||||
struct S *p = &vla3[0];
|
||||
|
||||
p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[3] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
|
||||
sink (vla3);
|
||||
}
|
||||
|
||||
void access_vla2_3_ptr (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla2_3[2 < n ? 2 : n][3 < n ? 3 : n];
|
||||
struct S *p = &vla2_3[0][0];
|
||||
|
||||
p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[6] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
|
||||
sink (vla2_3);
|
||||
}
|
||||
|
||||
void access_vla3_4_5_ptr (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla3_4_5[3 < n ? 3 : n][4 < n ? 4 : n][5 < n ? 5 : n];
|
||||
struct S *p = &vla3_4_5[0][0][0];
|
||||
|
||||
p[0] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = s; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[60] = s; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
|
||||
sink (vla3_4_5);
|
||||
}
|
||||
|
||||
// { dg-prune-output "empty struct has size 0 in C" }
|
|
@ -158,7 +158,7 @@ void test_memcpy_overflow (char *d, const char *s, size_t n)
|
|||
but known access size is detected. This works except with small
|
||||
sizes that are powers of 2 due to bug . */
|
||||
T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 1);
|
||||
T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 2); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 2 accessing array " "bug " { xfail non_strict_align } } */
|
||||
T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 2); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
T (char, 1, arr + SR (DIFF_MAX - 2, DIFF_MAX), s, 3); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 3 accessing array " "memcpy" } */
|
||||
T (char, 1, arr + SR (DIFF_MAX - 4, DIFF_MAX), s, 5); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 5 accessing array " "memcpy" } */
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ void test_memcpy_bounds_memarray_range (void)
|
|||
|
||||
TM (ma.a5, ma.a5 + i, ma.a5, 1);
|
||||
TM (ma.a5, ma.a5 + i, ma.a5, 3);
|
||||
TM (ma.a5, ma.a5 + i, ma.a5, 5);
|
||||
TM (ma.a5, ma.a5 + i, ma.a5, 5); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
TM (ma.a5, ma.a5 + i, ma.a5, 7); /* diagnosed with -Warray-bounds=2 */
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,17 @@ void test_memcpy_bounds_memarray_range (void)
|
|||
|
||||
TM (ma.a5, ma.a5 + j, ma.a5, 1);
|
||||
TM (ma.a5, ma.a5 + j, ma.a5, 3);
|
||||
TM (ma.a5, ma.a5 + j, ma.a5, 5);
|
||||
|
||||
/* The copy below is invalid for two reasons: 1) it overlaps and 2) it
|
||||
writes past the end of ma.a5. The warning is a little cryptic here
|
||||
because the GIMPLE is:
|
||||
_4 = &ma.a5 + prephitmp_14;
|
||||
MEM <unsigned char[5]> [(char * {ref-all})_4]
|
||||
= MEM <unsigned char[5]> [(char * {ref-all})&ma];
|
||||
and could be improved. Just verify that one is issued but not its
|
||||
full text. */
|
||||
TM (ma.a5, ma.a5 + j, ma.a5, 5); /* { dg-warning "\\\[-Warray-bounds" } */
|
||||
|
||||
TM (ma.a5, ma.a5 + j, ma.a5, 7); /* { dg-warning "offset \\\[5, 7] from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]. at offset 0" } */
|
||||
TM (ma.a5, ma.a5 + j, ma.a5, 9); /* { dg-warning "offset \\\[5, 9] from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]. at offset 0" } */
|
||||
}
|
||||
|
|
144
gcc/testsuite/c-c++-common/Warray-bounds-9.c
Normal file
144
gcc/testsuite/c-c++-common/Warray-bounds-9.c
Normal file
|
@ -0,0 +1,144 @@
|
|||
/* PR tree-optimization/99121 - ICE in -Warray-bounds on a multidimensional
|
||||
VLA
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
|
||||
|
||||
#define NOIPA __attribute__ ((noipa))
|
||||
|
||||
void sink (void*, ...);
|
||||
#define T(a, x) sink (a, x)
|
||||
|
||||
|
||||
NOIPA void a_0_n (int n)
|
||||
{
|
||||
int a[0][n];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void a_n_0 (int n)
|
||||
{
|
||||
int a[n][0];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
|
||||
NOIPA void a_1_n_0 (int n)
|
||||
{
|
||||
int a[1][n][0];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void a_1_0_n (int n)
|
||||
{
|
||||
int a[1][0][n];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void a_0_1_n (int n)
|
||||
{
|
||||
int a[0][1][n];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void a_0_n_1 (int n)
|
||||
{
|
||||
int a[0][n][1];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void a_n_0_n (int n)
|
||||
{
|
||||
int a[n][0][n];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void a_n_n_0 (int n)
|
||||
{
|
||||
int a[n][n][0];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void a_0_n_n (int n)
|
||||
{
|
||||
int a[0][n][n];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void a_0_0_n (int n)
|
||||
{
|
||||
int a[0][0][n];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void a_n_0_0 (int n)
|
||||
{
|
||||
int a[n][0][0];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[0]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((char *) a)[1]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
T (a, ((float *) a)[n]); // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void a_n_n_n (int n)
|
||||
{
|
||||
int a[n][n][n];
|
||||
|
||||
sink (a);
|
||||
|
||||
T (a, ((int *) a)[-1]); // { dg-warning "\\\[-Warray-bounds" "pr99140" }
|
||||
T (a, ((int *) a)[0]);
|
||||
T (a, ((char *) a)[1]);
|
||||
T (a, ((float *) a)[n]);
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
// { dg-skip-if "" { *-*-* } { "*" } { "-O2" } }
|
||||
// { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
|
||||
// { dg-additional-sources "asan_globals_test-wrapper.cc" }
|
||||
// { dg-options "-std=c++11 -fsanitize=address -fno-builtin -Wall -Werror -Wno-alloc-size-larger-than -Wno-stringop-overflow -g -DASAN_UAR=0 -DASAN_HAS_EXCEPTIONS=1 -DASAN_HAS_BLACKLIST=0 -DSANITIZER_USE_DEJAGNU_GTEST=1 -lasan -lpthread" }
|
||||
// { dg-options "-std=c++11 -fsanitize=address -fno-builtin -Wall -Werror -Wno-alloc-size-larger-than -Wno-array-bounds -Wno-stringop-overflow -g -DASAN_UAR=0 -DASAN_HAS_EXCEPTIONS=1 -DASAN_HAS_BLACKLIST=0 -DSANITIZER_USE_DEJAGNU_GTEST=1 -lasan -lpthread" }
|
||||
// { dg-additional-options "-ldl" { target { ! *-*-freebsd* } } }
|
||||
// { dg-additional-options "-DASAN_NEEDS_SEGV=1" { target { ! arm*-*-* } } }
|
||||
// { dg-additional-options "-DASAN_LOW_MEMORY=1 -DASAN_NEEDS_SEGV=0" { target arm*-*-* } }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* PR c++/95768 - pretty-printer ICE on -Wuninitialized with allocated storage
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wall" } */
|
||||
{ dg-options "-O2 -Wall -Wno-array-bounds" } */
|
||||
|
||||
extern "C" void *malloc (__SIZE_TYPE__);
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ void sink (void*);
|
|||
void warn_op_new ()
|
||||
{
|
||||
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
|
||||
// { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 }
|
||||
// { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
|
||||
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
|
||||
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
|
||||
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
|
||||
|
@ -44,7 +44,7 @@ void warn_op_array_new ()
|
|||
#define OP_NEW(n) operator new[] (n)
|
||||
|
||||
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
|
||||
// { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 }
|
||||
// { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
|
||||
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
|
||||
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
|
||||
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
|
||||
|
|
|
@ -20,7 +20,7 @@ void sink (void*);
|
|||
void warn_op_new ()
|
||||
{
|
||||
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
|
||||
// { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(std::size_t, const std::nothrow_t.\\\)'" "note" { target *-*-* } .-1 }
|
||||
// { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
|
||||
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
|
||||
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
|
||||
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
|
||||
|
@ -46,7 +46,7 @@ void warn_op_array_new ()
|
|||
#define OP_NEW(n) operator new[] (n, std::nothrow)
|
||||
|
||||
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
|
||||
// { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(std::size_t, const std::nothrow_t&\\\)'" "note" { target *-*-* } .-1 }
|
||||
// { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
|
||||
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
|
||||
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
|
||||
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
|
||||
|
|
|
@ -20,7 +20,7 @@ void sink (void*);
|
|||
void warn_new ()
|
||||
{
|
||||
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
|
||||
// { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 }
|
||||
// { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
|
||||
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
|
||||
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
|
||||
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
|
||||
|
@ -46,7 +46,7 @@ void warn_array_new ()
|
|||
#define NEW(n) new char [n]
|
||||
|
||||
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
|
||||
// { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(\(long \)?unsigned int\\\)'" "note" { target *-*-* } .-1 }
|
||||
// { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
|
||||
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
|
||||
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
|
||||
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
|
||||
|
|
|
@ -24,7 +24,7 @@ void sink (void*);
|
|||
void warn_nothrow_new ()
|
||||
{
|
||||
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
|
||||
// { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new\\\(std::size_t, const std::nothrow_t.\\\)'" "note" { target *-*-* } .-1 }
|
||||
// { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
|
||||
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
|
||||
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
|
||||
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
|
||||
|
@ -50,7 +50,7 @@ void warn_nothrow_array_new ()
|
|||
#define NEW(n) new (std::nothrow) char [n]
|
||||
|
||||
T (int32_t, 0, 0); // { dg-warning "array subscript 0 is outside array bounds of 'int32_t \\\[0]'" }
|
||||
// { dg-message "referencing an object of size \\d allocated by 'void\\\* operator new \\\[]\\\(std::size_t, const std::nothrow_t&\\\)'" "note" { target *-*-* } .-1 }
|
||||
// { dg-message "object of size \\d allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" { target *-*-* } .-1 }
|
||||
T (int32_t, 1, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[1]'" }
|
||||
T (int32_t, 2, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[2]'" }
|
||||
T (int32_t, 3, 0); // { dg-warning "array subscript 'int32_t {aka (long )?int}\\\[0]' is partly outside array bounds of 'unsigned char \\\[3]'" }
|
||||
|
|
|
@ -8,7 +8,7 @@ void foo (int *);
|
|||
void
|
||||
bar (void)
|
||||
{
|
||||
A b; // { dg-message "while referencing" }
|
||||
A b; // { dg-message "at offset -\\d into object 'b' of size 4" "note" }
|
||||
int *p = &b;
|
||||
int *x = (p - 1); // { dg-warning "outside array bounds" }
|
||||
foo (x);
|
||||
|
|
|
@ -35,7 +35,7 @@ void sink (void*);
|
|||
|
||||
void warn_derived_ctor_access_new_decl ()
|
||||
{
|
||||
char a[sizeof (D1)]; // { dg-message "referencing 'a'" "note" }
|
||||
char a[sizeof (D1)]; // { dg-message "at offset 1 into object 'a' of size 40" "note" }
|
||||
char *p = a;
|
||||
++p;
|
||||
D1 *q = new (p) D1;
|
||||
|
@ -44,7 +44,7 @@ void warn_derived_ctor_access_new_decl ()
|
|||
|
||||
void warn_derived_ctor_access_new_alloc ()
|
||||
{
|
||||
char *p = (char*)operator new (sizeof (D1)); // { dg-message "referencing an object of size \\d+ allocated by 'void\\\* operator new\\\(" "note" }
|
||||
char *p = (char*)operator new (sizeof (D1)); // { dg-message "at offset 1 into object of size \\d+ allocated by '\[^\n\r]*operator new\[^\n\r]*'" "note" }
|
||||
++p;
|
||||
D1 *q = new (p) D1;
|
||||
sink (q);
|
||||
|
@ -52,7 +52,7 @@ void warn_derived_ctor_access_new_alloc ()
|
|||
|
||||
void warn_derived_ctor_access_new_array_decl ()
|
||||
{
|
||||
char b[sizeof (D1) * 2]; // { dg-message "referencing 'b'" "note" }
|
||||
char b[sizeof (D1) * 2]; // { dg-message "at offset \\d+ into object 'b' of size 80" "note" }
|
||||
char *p = b;
|
||||
++p;
|
||||
D1 *q = new (p) D1[2];
|
||||
|
@ -61,7 +61,7 @@ void warn_derived_ctor_access_new_array_decl ()
|
|||
|
||||
void warn_derived_ctor_access_new_array_alloc ()
|
||||
{
|
||||
char *p = new char[sizeof (D1) * 2]; // { dg-message "referencing an object of size \\d+ allocated by 'void\\\* operator new \\\[]\\\(" "note" }
|
||||
char *p = new char[sizeof (D1) * 2]; // { dg-message "at offset \\d+ into object of size \\d+ allocated by '\[^\n\r]*operator new\[^\n\r]*" "note" }
|
||||
++p;
|
||||
D1 *q = new (p) D1[2];
|
||||
sink (q);
|
||||
|
|
|
@ -44,7 +44,7 @@ void test_narrow (void)
|
|||
T (p1[-1]);
|
||||
T (p1[ 0]);
|
||||
T (p1[ 1]);
|
||||
T (p1[ 2]); /* { dg-warning "array subscript \\\[3, 4] is outside array bounds of .char\\\[3]." } */
|
||||
T (p1[ 2]); /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */
|
||||
T (p1[ 3]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .char\\\[3]." } */
|
||||
|
||||
T (&p1[-3]); /* { dg-warning "array subscript \\\[-2, -1] is outside array bounds of .char\\\[3]." "bug" { xfail *-*-* } } */
|
||||
|
@ -55,7 +55,7 @@ void test_narrow (void)
|
|||
T (&p1[ 2]);
|
||||
T (&p1[ 3]); /* { dg-warning "array subscript \\\[4, 6] is outside array bounds of .char\\\[3]." "bug" { xfail *-*-* } } */
|
||||
|
||||
T (p2[-4]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
|
||||
T (p2[-4]); /* { dg-warning "subscript \\\[-2, -1\\\] is outside array bounds of .char\\\[3]." } */
|
||||
T (p2[-3]);
|
||||
T (p2[-2]);
|
||||
T (p2[-1]);
|
||||
|
@ -64,19 +64,19 @@ void test_narrow (void)
|
|||
/* Even though the lower bound of p3's offsets is in bounds, in order
|
||||
to subtract 4 from p3 and get a dereferenceable pointer its value
|
||||
would have to be out-of-bounds. */
|
||||
T (p3[-4]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
|
||||
T (p3[-4]); /* { dg-warning "array subscript -1 is outside array bounds of .char\\\[3]." } */
|
||||
T (p3[-3]);
|
||||
T (p3[-2]);
|
||||
T (p3[-1]);
|
||||
T (p3[ 0]); /* { dg-warning "array subscript \\\[3, 6] is outside array bounds of .char\\\[3]." } */
|
||||
T (p3[ 0]); /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */
|
||||
|
||||
T (p4[-4]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
|
||||
T (p4[-3]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
|
||||
T (p4[-2]); /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
|
||||
|
||||
/* The final subscripts below are invalid. */
|
||||
T (p4[-1]); /* { dg-warning "array subscript \\\[3, 7] is outside array bounds of .char\\\[3]." } */
|
||||
T (p4[ 0]); /* { dg-warning "array subscript \\\[4, 8] is outside array bounds of .char\\\[3]." } */
|
||||
T (p4[-1]); /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */
|
||||
T (p4[ 0]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .char\\\[3]." } */
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,7 +114,7 @@ void test_wide (void)
|
|||
T (p1[ 0]);
|
||||
T (p1[ 1]);
|
||||
T (p1[ 2]);
|
||||
T (p1[ 3]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
T (p1[ 3]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
|
||||
T (&p1[-1]);
|
||||
T (&p1[ 0]);
|
||||
|
@ -133,18 +133,18 @@ void test_wide (void)
|
|||
/* Even though the lower bound of p3's offsets is in bounds, in order
|
||||
to subtract 5 from p3 and get a dereferenceable pointer its value
|
||||
would have to be out-of-bounds. */
|
||||
T (p3[-5]); /* { dg-warning "intermediate array offset 5 is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
T (p3[-5]); /* { dg-warning "array subscript \\\[-2, -1\\\] is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
T (p3[-4]);
|
||||
T (p3[-3]);
|
||||
T (p3[-2]);
|
||||
T (p3[-1]);
|
||||
T (p3[ 0]);
|
||||
T (p3[ 1]); /* { dg-warning "array subscript \\\[4, 7] is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
T (p3[ 1]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
|
||||
T (p4[-5]); /* { dg-warning "intermediate array offset 5 is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
T (p4[-5]); /* { dg-warning "array subscript -1 is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
T (p4[-4]);
|
||||
T (p4[-3]);
|
||||
T (p4[-2]);
|
||||
T (p4[-1]);
|
||||
T (p4[ 0]); /* { dg-warning "array subscript \\\[4, 8] is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
T (p4[ 0]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ void test_global_short_2dim_array (void)
|
|||
T (&p[1]);
|
||||
T (&p[2]);
|
||||
T (&p[3]);
|
||||
T (&p[16]); /* { dg-warning "subscript 16 is \(above|outside\) array bounds of .short int\\\[3]" } */
|
||||
T (&p[16]); /* { dg-warning "subscript 16 is \(above|outside\) array bounds of .short int\\\[3]" "pr??????" { xfail *-*-* } } */
|
||||
T (&p[MAX]); /* { dg-warning "subscript -?\[0-9\]+ is \(above|outside\) array bounds of .short int\\\[3]" } */
|
||||
}
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ void narrow_ptr_deref_range (ptrdiff_t i, size_t j)
|
|||
T (*p);
|
||||
|
||||
p = S1 + SR (2, 3);
|
||||
T (*p); /* { dg-warning "array subscript \\\[2, 3] is outside array bounds of .char\\\[2]." } */
|
||||
T (*p); /* { dg-warning "array subscript 2 is outside array bounds of .char\\\[2]." } */
|
||||
|
||||
p = S1 + SR (9, 99);
|
||||
T (*p); /* { dg-warning "array subscript \\\[9, 99] is outside array bounds of .char\\\[2]." } */
|
||||
|
@ -198,7 +198,7 @@ void narrow_ptr_deref_range (ptrdiff_t i, size_t j)
|
|||
T (*p);
|
||||
|
||||
p = S8 + SR (9, 123);
|
||||
T (*p); /* { dg-warning "array subscript \\\[9, 123] is outside array bounds of .char\\\[9]." } */
|
||||
T (*p); /* { dg-warning "array subscript 9 is outside array bounds of .char\\\[9]." } */
|
||||
|
||||
{
|
||||
const char *p1 = S3 + i;
|
||||
|
@ -226,7 +226,7 @@ void narrow_ptr_deref_range (ptrdiff_t i, size_t j)
|
|||
T (*p1);
|
||||
T (*p2);
|
||||
T (*p3);
|
||||
T (*p4); /* { dg-warning "array subscript \\\[4, \[0-9\]+] is outside array bounds of .char\\\[4]." } */
|
||||
T (*p4); /* { dg-warning "array subscript 4 is outside array bounds of .char\\\[4]." } */
|
||||
T (*p5); /* { dg-warning "array subscript \\\[5, \[0-9\]+] is outside array bounds of .char\\\[4]." } */
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ void narrow_ptr_index_range (void)
|
|||
T (p[SR (-8, 0)]);
|
||||
T (p[SR (0, MAX)]);
|
||||
T (p[SR (1, 9)]);
|
||||
T (p[SR (8, 9)]); /* { dg-warning "array subscript \\\[8, 9] is outside array bounds of .char\\\[8]." } */
|
||||
T (p[SR (8, 9)]); /* { dg-warning "array subscript 8 is outside array bounds of .char\\\[8]." } */
|
||||
|
||||
p = S7 + SR (4, 6);
|
||||
T (p[5]); /* { dg-warning "array subscript \\\[9, 11] is outside array bounds of .char\\\[8]." } */
|
||||
|
|
|
@ -87,7 +87,7 @@ void wide_ptr_deref_range (ptrdiff_t i, size_t j)
|
|||
T (*p);
|
||||
|
||||
p = W8 + SR (9, 123);
|
||||
T (*p); /* { dg-warning "array subscript \\\[9, 123] is outside array bounds of .\[a-z \]+\\\[9]." } */
|
||||
T (*p); /* { dg-warning "array subscript 9 is outside array bounds of .\[a-z \]+\\\[9]." } */
|
||||
}
|
||||
|
||||
void wide_ptr_index_range (void)
|
||||
|
@ -99,7 +99,7 @@ void wide_ptr_index_range (void)
|
|||
T (p[SR (-8, 0)]);
|
||||
T (p[SR (0, MAX)]);
|
||||
T (p[SR (1, 9)]);
|
||||
T (p[SR (8, 9)]); /* { dg-warning "array subscript \\\[8, 9] is outside array bounds of .\[a-z \]+\\\[8]." } */
|
||||
T (p[SR (8, 9)]); /* { dg-warning "array subscript 8 is outside array bounds of .\[a-z \]+\\\[8]." } */
|
||||
|
||||
p = W7 + SR (4, 6);
|
||||
T (p[5]); /* { dg-warning "array subscript \\\[9, 11] is outside array bounds of .\[a-z \]+\\\[8]." } */
|
||||
|
@ -123,7 +123,7 @@ void wide_ptr_index_range_1 (void)
|
|||
int i = SR (1, 2);
|
||||
const wchar_t *p1 = W2 + i;
|
||||
|
||||
T (p1[2]); /* { dg-warning "array subscript \\\[3, 4] is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
T (p1[2]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,17 +140,17 @@ void wide_ptr_index_range_chain (void)
|
|||
T (p1[-1]);
|
||||
T (p1[0]);
|
||||
T (p1[1]);
|
||||
T (p1[2]); /* { dg-warning "array subscript \\\[3, 4] is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
T (p1[2]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
|
||||
T (p2[-5]); /* { dg-warning "array subscript \\\[-3, -1] is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
T (p2[-4]);
|
||||
T (p2[-5]); /* { dg-warning "array subscript \\\[-3, -2] is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
T (p2[-4]); /* { dg-warning "array subscript \\\[-2, -1] is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
T (p2[-1]);
|
||||
T (p2[0]);
|
||||
T (p2[1]); /* { dg-warning "array subscript \\\[3, 5] is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
T (p2[1]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
|
||||
T (p3[0]); /* { dg-warning "array subscript \\\[3, 6] is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
T (p3[1]); /* { dg-warning "array subscript \\\[4, 7] is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
T (p3[9999]); /* { dg-warning "array subscript \\\[10002, 10005] is outside array bounds of .\[a-z \]+\\\[3]." "" { target size20plus} } */
|
||||
T (p3[0]); /* { dg-warning "array subscript 3 is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
T (p3[1]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[3]." } */
|
||||
T (p3[9999]); /* { dg-warning "array subscript 10002 is outside array bounds of .\[a-z \]+\\\[3]." "" { target size20plus} } */
|
||||
/* { dg-warning "array subscript \\\[-6382, -6379] is outside array bounds of .\[a-z \]+\\\[3]." "" { target { ! size20plus } } .-1 } */
|
||||
/* Large offsets are indistinguishable from negative values. */
|
||||
T (p3[DIFF_MAX]); /* { dg-warning "array subscript" "bug" { xfail *-*-* } } */
|
||||
|
@ -166,9 +166,9 @@ void wide_ptr_index_range_chain (void)
|
|||
T (p1[-2]);
|
||||
T (p1[1]);
|
||||
T (p1[2]);
|
||||
T (p1[3]); /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
T (p1[3]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
|
||||
T (p3[1]); /* { dg-warning "array subscript \\\[4, 7] is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
T (p3[1]); /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,5 +180,5 @@ void wide_ptr_index_range_4 (void)
|
|||
const wchar_t *p3 = p2 + i;
|
||||
const wchar_t *p4 = p3 + i;
|
||||
|
||||
T (p4[1]); /* { dg-warning "array subscript \\\[5, 9] is outside array bounds of .\[a-z \]+\\\[5]." } */
|
||||
T (p4[1]); /* { dg-warning "array subscript 5 is outside array bounds of .\[a-z \]+\\\[5]." } */
|
||||
}
|
||||
|
|
|
@ -83,17 +83,17 @@ void ptr_idx_range (void)
|
|||
|
||||
i = SR (0, 1);
|
||||
|
||||
T (i, (int[]){ }); // { dg-warning "array subscript \\\[0, 1] is outside array bounds of 'int\\\[0]'" }
|
||||
T (i, (int[]){ }); // { dg-warning "array subscript 0 is outside array bounds of 'int\\\[0]'" }
|
||||
T (i, (int[]){ 1 });
|
||||
|
||||
i = SR (1, 2);
|
||||
T (i, (int[]){ 1 }); // { dg-warning "array subscript \\\[1, 2] is outside array bounds of 'int\\\[1]'" }
|
||||
T (i, (int[]){ 1 }); // { dg-warning "array subscript 1 is outside array bounds of 'int\\\[1]'" }
|
||||
|
||||
i = SR (2, 3);
|
||||
T (i, (int[]){ 1, 2, 3 });
|
||||
|
||||
i = SR (3, 4);
|
||||
T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript \\\[3, 4] is outside array bounds of 'int\\\[3]'" }
|
||||
T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript 3 is outside array bounds of 'int\\\[3]'" }
|
||||
}
|
||||
|
||||
/* Some of the invalid accesses above also trigger -Wuninitialized.
|
||||
|
|
|
@ -83,17 +83,17 @@ void ptr_idx_range (void)
|
|||
|
||||
i = SR (0, 1);
|
||||
|
||||
T (i, (int[]){ }); // { dg-warning "array subscript \\\[0, 1] is outside array bounds of 'int\\\[0]'" }
|
||||
T (i, (int[]){ }); // { dg-warning "array subscript 0 is outside array bounds of 'int\\\[0]'" }
|
||||
T (i, (int[]){ 1 });
|
||||
|
||||
i = SR (1, 2);
|
||||
T (i, (int[]){ 1 }); // { dg-warning "array subscript \\\[1, 2] is outside array bounds of 'int\\\[1]'" }
|
||||
T (i, (int[]){ 1 }); // { dg-warning "array subscript 1 is outside array bounds of 'int\\\[1]'" }
|
||||
|
||||
i = SR (2, 3);
|
||||
T (i, (int[]){ 1, 2, 3 });
|
||||
|
||||
i = SR (3, 4);
|
||||
T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript \\\[3, 4] is outside array bounds of 'int\\\[3]'" }
|
||||
T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript 3 is outside array bounds of 'int\\\[3]'" }
|
||||
}
|
||||
|
||||
/* Some of the invalid accesses above also trigger -Wuninitialized.
|
||||
|
|
|
@ -36,7 +36,7 @@ extern struct Ax ax;
|
|||
|
||||
void fax_extern (void)
|
||||
{
|
||||
sink (strlen (ax.a - 2)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
|
||||
sink (strlen (ax.a - 2)); // { dg-warning "\\\[-Warray-bounds" "pr93514" }
|
||||
sink (strlen (ax.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
|
||||
sink (strlen (ax.a));
|
||||
sink (strlen (ax.a + 123));
|
||||
|
|
|
@ -14,7 +14,7 @@ void sink (void*);
|
|||
|
||||
void byte_store_to_decl (void)
|
||||
{
|
||||
struct S6 { char a[6]; } s; // { dg-message "referencing 's'" }
|
||||
struct S6 { char a[6]; } s; // { dg-message "at offset 6 into object 's' of size 6" "note" }
|
||||
|
||||
char *p = (char*)&s;
|
||||
|
||||
|
@ -27,7 +27,7 @@ void byte_store_to_decl (void)
|
|||
|
||||
void word_store_to_decl (void)
|
||||
{
|
||||
struct S6 { char a[6]; } s; // { dg-message "referencing 's'" }
|
||||
struct S6 { char a[6]; } s; // { dg-message "at offset 5 into object 's' of size 6" "note" }
|
||||
|
||||
char *p = (char*)&s;
|
||||
|
||||
|
@ -43,7 +43,7 @@ void word_store_to_decl (void)
|
|||
void word_store_to_alloc (void)
|
||||
{
|
||||
struct S6 { char a[6]; } *p;
|
||||
p = alloca (sizeof *p); // { dg-message "referencing an object of size 6 allocated by 'alloca'" }
|
||||
p = alloca (sizeof *p); // { dg-message "at offset 5 into object of size 6 allocated by 'alloca'" "note" }
|
||||
|
||||
int16_t *q = (int16_t*)((char*)p + 1);
|
||||
|
||||
|
|
|
@ -117,14 +117,14 @@ void test_alloca_int16_range (unsigned n)
|
|||
}
|
||||
|
||||
{
|
||||
p = alloca (UR (0, 1)); // { dg-message "object of size between 0 and 1 allocated by '__builtin_alloca'" }
|
||||
p = alloca (UR (0, 1)); // { dg-message "at offset \\d+ into object of size \\\[0, 1] allocated by '__builtin_alloca'" "note" }
|
||||
sink (p);
|
||||
T (p[0]); // { dg-warning "subscript 'int16_t {aka short int}\\\[0\\\]' is partly outside array bounds of 'unsigned char\\\[1]'" }
|
||||
T (p[1]); // { dg-warning "subscript 1 is outside array bounds of 'int16_t\\\[0]'" }
|
||||
}
|
||||
|
||||
{
|
||||
p = alloca (UR (0, 2)); // { dg-message "object of size between 0 and 2 allocated by '__builtin_alloca'" }
|
||||
p = alloca (UR (0, 2)); // { dg-message "at offset \\d+ into object of size \\\[0, 2] allocated by '__builtin_alloca'" "note" }
|
||||
sink (p);
|
||||
sink (p[0]);
|
||||
sink (p[1]); // { dg-warning "subscript 1 is outside array bounds of 'int16_t\\\[1]'" }
|
||||
|
@ -132,7 +132,7 @@ void test_alloca_int16_range (unsigned n)
|
|||
}
|
||||
|
||||
{
|
||||
p = alloca (UR (0, 3)); // { dg-message "object of size between 0 and 3 allocated by '__builtin_alloca'" }
|
||||
p = alloca (UR (0, 3)); // { dg-message "at offset \\d+ into object of size \\\[0, 3] allocated by '__builtin_alloca'" "note" }
|
||||
sink (p);
|
||||
T (p[0]);
|
||||
T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" }
|
||||
|
@ -141,7 +141,7 @@ void test_alloca_int16_range (unsigned n)
|
|||
}
|
||||
|
||||
{
|
||||
p = alloca (UR (1, 3)); // { dg-message "object of size between 1 and 3 allocated by '__builtin_alloca'" }
|
||||
p = alloca (UR (1, 3)); // { dg-message "at offset 1|2|3 into object of size \\\[1, 3] allocated by '__builtin_alloca'" "note" }
|
||||
sink (p);
|
||||
T (p[0]);
|
||||
T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" }
|
||||
|
@ -150,7 +150,7 @@ void test_alloca_int16_range (unsigned n)
|
|||
}
|
||||
|
||||
{
|
||||
p = alloca (UR (2, 3)); // { dg-message "object of size between 2 and 3 allocated by '__builtin_alloca'" }
|
||||
p = alloca (UR (2, 3)); // { dg-message "at offset 2|4 into object of size \\\[2, 3] allocated by '__builtin_alloca'" "note" }
|
||||
sink (p);
|
||||
T (p[0]);
|
||||
T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" }
|
||||
|
@ -159,7 +159,7 @@ void test_alloca_int16_range (unsigned n)
|
|||
}
|
||||
|
||||
{
|
||||
p = alloca (UR (3, 4)); // { dg-message "object of size between 3 and 4 allocated by '__builtin_alloca'" }
|
||||
p = alloca (UR (3, 4)); // { dg-message "at offset 4|6 into object of size \\\[3, 4] allocated by '__builtin_alloca'" "note" }
|
||||
sink (p);
|
||||
T (p[0]);
|
||||
T (p[1]);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Verify that storing a bigger vector into smaller space is diagnosed.
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Warray-bounds" } */
|
||||
{ dg-options "-O2 -Warray-bounds -Wno-stringop-overflow" } */
|
||||
|
||||
typedef __INT16_TYPE__ int16_t;
|
||||
typedef __attribute__ ((__vector_size__ (32))) char C32;
|
||||
|
|
135
gcc/testsuite/gcc.dg/Warray-bounds-77.c
Normal file
135
gcc/testsuite/gcc.dg/Warray-bounds-77.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
/* PR middle-end/100137 - -Warray-bounds false positive on varying offset
|
||||
plus negative
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wall" } */
|
||||
|
||||
extern char ax[], a1[1], a2[2], a3[3], a4[4], a5[5];
|
||||
|
||||
int* ptr;
|
||||
#define X (*ptr++)
|
||||
|
||||
|
||||
__attribute__ ((noipa)) void
|
||||
array_plus_var_minus_cstint (int i, int j)
|
||||
{
|
||||
{
|
||||
const char *p = ax;
|
||||
p += i;
|
||||
X = p[-1];
|
||||
X = p[-123];
|
||||
}
|
||||
|
||||
{
|
||||
const char *p = a1;
|
||||
p += i;
|
||||
X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-2]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
X = p[-3]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
{
|
||||
const char *p = a2;
|
||||
p += i;
|
||||
X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-3]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
{
|
||||
const char *p = a3;
|
||||
p += i;
|
||||
X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
X = p[-5]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
{
|
||||
const char *p = a4;
|
||||
p += i;
|
||||
X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-5]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
X = p[-6]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
{
|
||||
const char *p = a5;
|
||||
p += i;
|
||||
p += j;
|
||||
X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-5]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-6]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__attribute__ ((noipa)) void
|
||||
array_plus_var_minus_cstlong (long i, long j)
|
||||
{
|
||||
{
|
||||
const char *p = ax;
|
||||
p += i;
|
||||
X = p[-1];
|
||||
X = p[-123];
|
||||
}
|
||||
|
||||
{
|
||||
const char *p = a1;
|
||||
p += i;
|
||||
X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-2]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
X = p[-3]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
{
|
||||
const char *p = a2;
|
||||
p += i;
|
||||
X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-3]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
{
|
||||
const char *p = a3;
|
||||
p += i;
|
||||
X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-4]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
X = p[-5]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
{
|
||||
const char *p = a4;
|
||||
p += i;
|
||||
X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-5]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
X = p[-6]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
{
|
||||
const char *p = a5;
|
||||
p += i;
|
||||
p += j;
|
||||
X = p[-1]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-2]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-3]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-4]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-5]; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
X = p[-6]; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
}
|
109
gcc/testsuite/gcc.dg/Warray-bounds-78.c
Normal file
109
gcc/testsuite/gcc.dg/Warray-bounds-78.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/* PR tree-optimization/99475 - bogus -Warray-bounds accessing an array
|
||||
element of empty structs
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wall -Wno-strict-aliasing" } */
|
||||
|
||||
typedef _Bool bool;
|
||||
|
||||
#define NOIPA __attribute__ ((noipa))
|
||||
|
||||
struct S { };
|
||||
|
||||
extern struct S sa3[3];
|
||||
extern struct S sa2_3[2][3];
|
||||
extern struct S sa3_4_5[3][4][5];
|
||||
|
||||
void sink (void*);
|
||||
|
||||
|
||||
NOIPA void access_sa3 (void)
|
||||
{
|
||||
((bool*)sa3)[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
((bool*)sa3)[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
((bool*)sa3)[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
((bool*)sa3)[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void access_sa3_ptr (void)
|
||||
{
|
||||
bool *p = (bool*)&sa3[0];
|
||||
|
||||
p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void access_sa2_3_ptr (void)
|
||||
{
|
||||
bool *p = (bool*)&sa2_3[0][0];
|
||||
|
||||
p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[6] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
NOIPA void access_sa3_4_5_ptr (struct S s, int i)
|
||||
{
|
||||
bool *p = (bool*)&sa3_4_5[0][0][0];
|
||||
|
||||
p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[60] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
}
|
||||
|
||||
|
||||
NOIPA void access_vla3 (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla3[3 < n ? 3 : n];
|
||||
|
||||
((bool*)vla3)[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
((bool*)vla3)[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
((bool*)vla3)[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
((bool*)vla3)[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
|
||||
sink (vla3);
|
||||
}
|
||||
|
||||
NOIPA void access_vla3_ptr (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla3[3 < n ? 3 : n];
|
||||
bool *p = (bool*)&vla3[0];
|
||||
|
||||
p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[3] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
|
||||
sink (vla3);
|
||||
}
|
||||
|
||||
NOIPA void access_vla2_3_ptr (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla2_3[2 < n ? 2 : n][3 < n ? 3 : n];
|
||||
bool *p = (bool*)&vla2_3[0][0];
|
||||
|
||||
p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[6] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
|
||||
sink (vla2_3);
|
||||
}
|
||||
|
||||
NOIPA void access_vla3_4_5_ptr (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla3_4_5[3 < n ? 3 : n][4 < n ? 4 : n][5 < n ? 5 : n];
|
||||
bool *p = (bool*)&vla3_4_5[0][0][0];
|
||||
|
||||
p[0] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
p[60] = __LINE__; // { dg-warning "\\\[-Warray-bounds" }
|
||||
|
||||
sink (vla3_4_5);
|
||||
}
|
||||
|
||||
// { dg-prune-output "empty struct has size 0 in C" }
|
112
gcc/testsuite/gcc.dg/Warray-bounds-79.c
Normal file
112
gcc/testsuite/gcc.dg/Warray-bounds-79.c
Normal file
|
@ -0,0 +1,112 @@
|
|||
/* PR tree-optimization/99475 - bogus -Warray-bounds accessing an array
|
||||
element of empty structs
|
||||
{ dg-do compile }
|
||||
{ dg-options "-O2 -Wall" } */
|
||||
|
||||
struct S
|
||||
{
|
||||
#if SOME_CONFIG_MACRO
|
||||
/* Suppose the contents are empty in the development configuration
|
||||
but non-empty in others. Out of bounds accesses to elements of
|
||||
the arrays below should be diagnosed in all configurations,
|
||||
including when S is empty, even if they are folded away. */
|
||||
int member;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct S sa3[3];
|
||||
extern struct S sa2_3[2][3];
|
||||
extern struct S sa3_4_5[3][4][5];
|
||||
|
||||
void sink (void*);
|
||||
|
||||
|
||||
void access_sa3 (void)
|
||||
{
|
||||
sa3[0] = (struct S){ };
|
||||
sa3[1] = (struct S){ };
|
||||
sa3[2] = (struct S){ };
|
||||
sa3[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
}
|
||||
|
||||
void access_sa3_ptr (void)
|
||||
{
|
||||
struct S *p = &sa3[0];
|
||||
|
||||
p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
}
|
||||
|
||||
void access_sa2_3_ptr (void)
|
||||
{
|
||||
struct S *p = &sa2_3[0][0];
|
||||
|
||||
p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[6] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
}
|
||||
|
||||
void access_sa3_4_5_ptr (struct S s, int i)
|
||||
{
|
||||
struct S *p = &sa3_4_5[0][0][0];
|
||||
|
||||
p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[60] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
}
|
||||
|
||||
|
||||
void access_vla3 (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla3[3 < n ? 3 : n];
|
||||
|
||||
vla3[0] = (struct S){ };
|
||||
vla3[1] = (struct S){ };
|
||||
vla3[2] = (struct S){ };
|
||||
vla3[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
|
||||
sink (vla3);
|
||||
}
|
||||
|
||||
void access_vla3_ptr (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla3[3 < n ? 3 : n];
|
||||
struct S *p = &vla3[0];
|
||||
|
||||
p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[3] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
|
||||
sink (vla3);
|
||||
}
|
||||
|
||||
void access_vla2_3_ptr (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla2_3[2 < n ? 2 : n][3 < n ? 3 : n];
|
||||
struct S *p = &vla2_3[0][0];
|
||||
|
||||
p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[6] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
|
||||
sink (vla2_3);
|
||||
}
|
||||
|
||||
void access_vla3_4_5_ptr (struct S s, unsigned n)
|
||||
{
|
||||
struct S vla3_4_5[3 < n ? 3 : n][4 < n ? 4 : n][5 < n ? 5 : n];
|
||||
struct S *p = &vla3_4_5[0][0][0];
|
||||
|
||||
p[0] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[1] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[2] = (struct S){ }; // { dg-bogus "\\\[-Warray-bounds" }
|
||||
p[60] = (struct S){ }; // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
|
||||
|
||||
sink (vla3_4_5);
|
||||
}
|
|
@ -112,7 +112,7 @@ void s2_warn_cstoff_cstidx (struct S2 *p)
|
|||
void s2_warn_varoff_cstdix (struct S2 *p, int i)
|
||||
{
|
||||
char *q = p->a + i;
|
||||
q[2] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" }
|
||||
q[2] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
|
||||
}
|
||||
|
||||
void s2_warn_cstoff_varidx (struct S2 *p, int i)
|
||||
|
@ -235,8 +235,8 @@ void si0_warn_cstoff_cstidx (struct Si0 *p)
|
|||
void si0_warn_varoff_cstdix (struct Si0 *p, int i)
|
||||
{
|
||||
char *q = p->a + i;
|
||||
q[1] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" }
|
||||
q[9] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" }
|
||||
q[1] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
|
||||
q[9] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
|
||||
}
|
||||
|
||||
void si0_warn_cstoff_varidx (struct Si0 *p, int i)
|
||||
|
@ -248,5 +248,5 @@ void si0_warn_cstoff_varidx (struct Si0 *p, int i)
|
|||
void si0_warn_varoff_varidx (struct Si0 *p, int i, int j)
|
||||
{
|
||||
char *q = p->a + i;
|
||||
q[j] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" }
|
||||
q[j] = __LINE__; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
|
||||
}
|
||||
|
|
|
@ -24,22 +24,22 @@ void nowarn_c32 (char c)
|
|||
sink (p);
|
||||
}
|
||||
|
||||
/* The tests below fail as a result of the hack for PR 96963. However,
|
||||
with -Wall, the invalid stores are diagnosed by -Warray-bounds which
|
||||
runs before vectorization and so doesn't need the hack. If/when
|
||||
-Warray changes to use compute_objsize() this will need adjusting. */
|
||||
/* The tests below failed as a result of the hack for PR 96963. However,
|
||||
with -Wall, the invalid stores were diagnosed by -Warray-bounds which
|
||||
runs before vectorization and so doesn't need the hack. Now that
|
||||
-Warray-bounds has changed to use compute_objsize() the tests pass. */
|
||||
|
||||
void warn_c32 (char c)
|
||||
{
|
||||
extern char warn_a32[32]; // { dg-message "at offset 32 into destination object 'warn_a32' of size 32" "pr97027" { xfail *-*-* } }
|
||||
extern char warn_a32[32]; // { dg-message "at offset 32 into destination object 'warn_a32' of size 32" "pr97027" }
|
||||
|
||||
void *p = warn_a32 + 1;
|
||||
*(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" { xfail *-*-* } }
|
||||
*(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" }
|
||||
|
||||
/* Verify a local variable too. */
|
||||
char a32[32];
|
||||
p = a32 + 1;
|
||||
*(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" { xfail *-*-* } }
|
||||
*(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" }
|
||||
sink (p);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ void nowarn_cond_escape (int c, int *x)
|
|||
void warn_cond_escape (int c, int *x)
|
||||
{
|
||||
extern char a3_2[3];
|
||||
extern char a5_2[5]; // { dg-message "at offset 5 into destination object 'a5_2'" }
|
||||
extern char a5_2[5]; // { dg-message "at offset 5 into object 'a5_2'" }
|
||||
|
||||
char *p;
|
||||
if (c)
|
||||
|
@ -84,5 +84,5 @@ void warn_cond_escape (int c, int *x)
|
|||
if (*x == 2)
|
||||
p[2] = 0;
|
||||
else if (*x == 5)
|
||||
p[5] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
|
||||
p[5] = 0; // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue