From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1930) id E89FD383802F; Wed, 7 Jul 2021 20:14:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E89FD383802F MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Martin Sebor To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-2132] Correct handling of variable offset minus constant in -Warray-bounds [PR100137] X-Act-Checkin: gcc X-Git-Author: Martin Sebor X-Git-Refname: refs/heads/master X-Git-Oldrev: 6278065af07634278ba30029d92a82b089969baa X-Git-Newrev: a110855667782dac7b674d3e328b253b3b3c919b Message-Id: <20210707201411.E89FD383802F@sourceware.org> Date: Wed, 7 Jul 2021 20:14:11 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Jul 2021 20:14:12 -0000 https://gcc.gnu.org/g:a110855667782dac7b674d3e328b253b3b3c919b commit r12-2132-ga110855667782dac7b674d3e328b253b3b3c919b Author: Martin Sebor Date: Wed Jul 7 14:05:25 2021 -0600 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. Diff: --- gcc/builtins.c | 69 +++++- gcc/builtins.h | 5 + gcc/gimple-array-bounds.cc | 336 ++++---------------------- gcc/testsuite/c-c++-common/Warray-bounds-10.c | 114 +++++++++ gcc/testsuite/c-c++-common/Warray-bounds-3.c | 4 +- gcc/testsuite/c-c++-common/Warray-bounds-4.c | 12 +- gcc/testsuite/c-c++-common/Warray-bounds-9.c | 144 +++++++++++ gcc/testsuite/g++.dg/asan/asan_test.C | 2 +- gcc/testsuite/g++.dg/pr95768.C | 2 +- gcc/testsuite/g++.dg/warn/Warray-bounds-10.C | 4 +- gcc/testsuite/g++.dg/warn/Warray-bounds-11.C | 4 +- gcc/testsuite/g++.dg/warn/Warray-bounds-12.C | 4 +- gcc/testsuite/g++.dg/warn/Warray-bounds-13.C | 4 +- gcc/testsuite/g++.dg/warn/Warray-bounds-17.C | 2 +- gcc/testsuite/g++.dg/warn/Warray-bounds-20.C | 8 +- gcc/testsuite/gcc.dg/Warray-bounds-29.c | 22 +- gcc/testsuite/gcc.dg/Warray-bounds-30.c | 2 +- gcc/testsuite/gcc.dg/Warray-bounds-31.c | 8 +- gcc/testsuite/gcc.dg/Warray-bounds-32.c | 26 +- gcc/testsuite/gcc.dg/Warray-bounds-52.c | 6 +- gcc/testsuite/gcc.dg/Warray-bounds-53.c | 6 +- gcc/testsuite/gcc.dg/Warray-bounds-58.c | 2 +- gcc/testsuite/gcc.dg/Warray-bounds-63.c | 6 +- gcc/testsuite/gcc.dg/Warray-bounds-66.c | 12 +- gcc/testsuite/gcc.dg/Warray-bounds-69.c | 2 +- gcc/testsuite/gcc.dg/Warray-bounds-77.c | 135 +++++++++++ gcc/testsuite/gcc.dg/Warray-bounds-78.c | 109 +++++++++ gcc/testsuite/gcc.dg/Warray-bounds-79.c | 112 +++++++++ gcc/testsuite/gcc.dg/Wstringop-overflow-34.c | 8 +- gcc/testsuite/gcc.dg/Wstringop-overflow-47.c | 14 +- gcc/testsuite/gcc.dg/Wstringop-overflow-61.c | 4 +- 31 files changed, 817 insertions(+), 371 deletions(-) diff --git a/gcc/builtins.c b/gcc/builtins.c index e52fe4291c8..39ab139b7e1 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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) { diff --git a/gcc/builtins.h b/gcc/builtins.h index e71f40c300a..a64ece3f1cd 100644 --- a/gcc/builtins.h +++ b/gcc/builtins.h @@ -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 diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc index 13f08685f8f..83b8db9755e 100644 --- a/gcc/gimple-array-bounds.cc +++ b/gcc/gimple-array-bounds.cc @@ -414,269 +414,72 @@ 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; + /* The type and size of the access. */ + tree axstype = TREE_TYPE (ref); + offset_int axssize = 0; + if (TREE_CODE (axstype) != UNION_TYPE) + if (tree access_size = TYPE_SIZE_UNIT (axstype)) + if (TREE_CODE (access_size) == INTEGER_CST) + axssize = wi::to_offset (access_size); - /* 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]; - } + access_ref aref; + if (!compute_objsize (ref, 1, &aref, ranges)) + return false; - 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; + if (aref.offset_in_range (axssize)) + return false; - offset_int nelts = arrbounds[1] / eltsize; - reftype = build_printable_array_type (reftype, nelts.to_uhwi ()); - } - else if (TREE_CODE (arg) == ADDR_EXPR) + if (TREE_CODE (aref.ref) == SSA_NAME) { - 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 + gimple *def = SSA_NAME_DEF_STMT (aref.ref); + if (is_gimple_call (def)) { - 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); + /* Save the allocation call and the low bound on the size. */ + alloc_stmt = def; + minbound = aref.sizrng[0]; } } - else - return false; - - offrange[0] += ioff; - offrange[1] += ioff; + + /* 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 = arrbounds[1]; + offset_int ubound = aref.sizrng[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] + const bool lboob = (aref.sizrng[1] == 0 || offrange[0] >= ubound - || offrange[1] < arrbounds[0]); + || 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. */ - tree axstype = TREE_TYPE (ref); - offset_int axssize = 0; - if (TREE_CODE (axstype) != UNION_TYPE) - if (tree access_size = TYPE_SIZE_UNIT (axstype)) - if (TREE_CODE (access_size) == INTEGER_CST) - axssize = wi::to_offset (access_size); - 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 " diff --git a/gcc/testsuite/c-c++-common/Warray-bounds-10.c b/gcc/testsuite/c-c++-common/Warray-bounds-10.c new file mode 100644 index 00000000000..cfe9a383410 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Warray-bounds-10.c @@ -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" } diff --git a/gcc/testsuite/c-c++-common/Warray-bounds-3.c b/gcc/testsuite/c-c++-common/Warray-bounds-3.c index aae4999ea13..3d7c7687374 100644 --- a/gcc/testsuite/c-c++-common/Warray-bounds-3.c +++ b/gcc/testsuite/c-c++-common/Warray-bounds-3.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 */ } diff --git a/gcc/testsuite/c-c++-common/Warray-bounds-4.c b/gcc/testsuite/c-c++-common/Warray-bounds-4.c index 22a23a12651..1f73f11943f 100644 --- a/gcc/testsuite/c-c++-common/Warray-bounds-4.c +++ b/gcc/testsuite/c-c++-common/Warray-bounds-4.c @@ -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 [(char * {ref-all})_4] + = MEM [(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" } */ } diff --git a/gcc/testsuite/c-c++-common/Warray-bounds-9.c b/gcc/testsuite/c-c++-common/Warray-bounds-9.c new file mode 100644 index 00000000000..be05775fa91 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Warray-bounds-9.c @@ -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]); +} diff --git a/gcc/testsuite/g++.dg/asan/asan_test.C b/gcc/testsuite/g++.dg/asan/asan_test.C index c62568f48ec..49933ab8e4d 100644 --- a/gcc/testsuite/g++.dg/asan/asan_test.C +++ b/gcc/testsuite/g++.dg/asan/asan_test.C @@ -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*-*-* } } diff --git a/gcc/testsuite/g++.dg/pr95768.C b/gcc/testsuite/g++.dg/pr95768.C index 5e2c8c44ad0..d34d5133134 100644 --- a/gcc/testsuite/g++.dg/pr95768.C +++ b/gcc/testsuite/g++.dg/pr95768.C @@ -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__); diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C index 4deea31fae0..4b758aadaa1 100644 --- a/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-10.C @@ -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]'" } diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-11.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-11.C index 45d271948e8..70b39122f78 100644 --- a/gcc/testsuite/g++.dg/warn/Warray-bounds-11.C +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-11.C @@ -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]'" } diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-12.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-12.C index 3f1555b9e1b..07fa351a86c 100644 --- a/gcc/testsuite/g++.dg/warn/Warray-bounds-12.C +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-12.C @@ -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]'" } diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-13.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-13.C index 890620dc70a..2d3e9dcfd68 100644 --- a/gcc/testsuite/g++.dg/warn/Warray-bounds-13.C +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-13.C @@ -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]'" } diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-17.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-17.C index 64fbd080123..518f9bb26fa 100644 --- a/gcc/testsuite/g++.dg/warn/Warray-bounds-17.C +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-17.C @@ -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); diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C index e142ea16787..a65b29e6269 100644 --- a/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-20.C @@ -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); diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-29.c b/gcc/testsuite/gcc.dg/Warray-bounds-29.c index 72c5d1cecf8..44e5bd36127 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-29.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-29.c @@ -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]." } */ } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-30.c b/gcc/testsuite/gcc.dg/Warray-bounds-30.c index 048a95d6dcf..b837ad0c36c 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-30.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-30.c @@ -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]" } */ } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-31.c b/gcc/testsuite/gcc.dg/Warray-bounds-31.c index 389afaf045d..921461a549d 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-31.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-31.c @@ -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]." } */ diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-32.c b/gcc/testsuite/gcc.dg/Warray-bounds-32.c index 9b5f3331735..02dac652211 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-32.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-32.c @@ -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]." } */ } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-52.c b/gcc/testsuite/gcc.dg/Warray-bounds-52.c index 729ad45d6ac..c7217ad4f7b 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-52.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-52.c @@ -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. diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-53.c b/gcc/testsuite/gcc.dg/Warray-bounds-53.c index 80db314b393..591cca28d27 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-53.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-53.c @@ -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. diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-58.c b/gcc/testsuite/gcc.dg/Warray-bounds-58.c index 849457e559f..616145b65a6 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-58.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-58.c @@ -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)); diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-63.c b/gcc/testsuite/gcc.dg/Warray-bounds-63.c index a3fc9188211..530e2c56452 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-63.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-63.c @@ -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); diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-66.c b/gcc/testsuite/gcc.dg/Warray-bounds-66.c index c61891f5c07..6ab3398c762 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-66.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-66.c @@ -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]); diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-69.c b/gcc/testsuite/gcc.dg/Warray-bounds-69.c index 5a955774124..80503f8d217 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-69.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-69.c @@ -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; diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-77.c b/gcc/testsuite/gcc.dg/Warray-bounds-77.c new file mode 100644 index 00000000000..6487613374d --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-77.c @@ -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" } + } +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-78.c b/gcc/testsuite/gcc.dg/Warray-bounds-78.c new file mode 100644 index 00000000000..73c335fd8a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-78.c @@ -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" } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-79.c b/gcc/testsuite/gcc.dg/Warray-bounds-79.c new file mode 100644 index 00000000000..b44ac9d3aa2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-79.c @@ -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); +} diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c index a1b103918cf..d9ca3447eb9 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c @@ -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" } } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c index 9bfc84af569..6412874e2f9 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c @@ -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); } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c index 7601679fac3..93c54c646c0 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c @@ -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" } }