]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Correct handling of variable offset minus constant in -Warray-bounds [PR100137]
authorMartin Sebor <msebor@redhat.com>
Wed, 7 Jul 2021 20:05:25 +0000 (14:05 -0600)
committerMartin Sebor <msebor@redhat.com>
Wed, 7 Jul 2021 20:06:59 +0000 (14:06 -0600)
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.

31 files changed:
gcc/builtins.c
gcc/builtins.h
gcc/gimple-array-bounds.cc
gcc/testsuite/c-c++-common/Warray-bounds-10.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Warray-bounds-3.c
gcc/testsuite/c-c++-common/Warray-bounds-4.c
gcc/testsuite/c-c++-common/Warray-bounds-9.c [new file with mode: 0644]
gcc/testsuite/g++.dg/asan/asan_test.C
gcc/testsuite/g++.dg/pr95768.C
gcc/testsuite/g++.dg/warn/Warray-bounds-10.C
gcc/testsuite/g++.dg/warn/Warray-bounds-11.C
gcc/testsuite/g++.dg/warn/Warray-bounds-12.C
gcc/testsuite/g++.dg/warn/Warray-bounds-13.C
gcc/testsuite/g++.dg/warn/Warray-bounds-17.C
gcc/testsuite/g++.dg/warn/Warray-bounds-20.C
gcc/testsuite/gcc.dg/Warray-bounds-29.c
gcc/testsuite/gcc.dg/Warray-bounds-30.c
gcc/testsuite/gcc.dg/Warray-bounds-31.c
gcc/testsuite/gcc.dg/Warray-bounds-32.c
gcc/testsuite/gcc.dg/Warray-bounds-52.c
gcc/testsuite/gcc.dg/Warray-bounds-53.c
gcc/testsuite/gcc.dg/Warray-bounds-58.c
gcc/testsuite/gcc.dg/Warray-bounds-63.c
gcc/testsuite/gcc.dg/Warray-bounds-66.c
gcc/testsuite/gcc.dg/Warray-bounds-69.c
gcc/testsuite/gcc.dg/Warray-bounds-77.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Warray-bounds-78.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Warray-bounds-79.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wstringop-overflow-34.c
gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
gcc/testsuite/gcc.dg/Wstringop-overflow-61.c

index e52fe4291c89b14a7e7e8b9e017dc0ff4270b482..39ab139b7e1c06c98d2db1aef2b3a6095ffbec63 100644 (file)
@@ -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)
        {
index e71f40c300a1e244b61409cda7dcdf893f79a2ee..a64ece3f1cd9aed195cd2e5ec5383d4a96e39bf8 100644 (file)
@@ -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
index 13f08685f8f905408c885aa5a4f821b6aaad0a8b..83b8db9755e84f83c96735a6f2cfb25320506d9b 100644 (file)
@@ -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 (file)
index 0000000..cfe9a38
--- /dev/null
@@ -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" }
index aae4999ea1348d2e4bde89a4edbde6de1d2da965..3d7c768737414f1c132ba10cfc486b08c3f4dc02 100644 (file)
@@ -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 */
 }
 
index 22a23a126512f5e4f9236affee9210179fe7dfa9..1f73f11943fe633a344f1f91728ea81813dd1f23 100644 (file)
@@ -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" } */
 }
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 (file)
index 0000000..be05775
--- /dev/null
@@ -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]);
+}
index c62568f48ecb2bf0f3ef50e2cb68130a6147e5b1..49933ab8e4da59980fbf8db4d71f4a0bf1e2a422 100644 (file)
@@ -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*-*-* } }
index 5e2c8c44ad00f0bdf21d56bb15a5a21fdc4e91fe..d34d513313469faa1dd9fdfb630ad4ec91700c07 100644 (file)
@@ -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__);
 
index 4deea31fae0340f4fe3bf59ae37dca176bc461e6..4b758aadaa164adffa6a9f42190cf9eb3c4048e2 100644 (file)
@@ -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]'" }
index 45d271948e88e5d0f407a9baa1db93a2a47d1b52..70b39122f78abea5e08a0d85833196dbc01970b0 100644 (file)
@@ -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]'" }
index 3f1555b9e1b1e1d81ee2b7fe79a83ff862a7b03c..07fa351a86ceb265616ebe5a9c83d9507e55ce86 100644 (file)
@@ -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]'" }
index 890620dc70a236cdfb4ad948c90d3d5350ce937a..2d3e9dcfd684f5c9eed46f927e603ab7c30c5a37 100644 (file)
@@ -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]'" }
index 64fbd080123404472883f46687cff0ef1ff6edd4..518f9bb26fabc0bb70841d1a67ee2436c64d7b49 100644 (file)
@@ -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);
index e142ea16787d72c65a11fac520ed1a8e245ed530..a65b29e62690122cd983702288220d60af1b6520 100644 (file)
@@ -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);
index 72c5d1cecf8b94ea0e31b61102a5d77158b8f2c3..44e5bd36127d16b934160ee93b66ce520125b73d 100644 (file)
@@ -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]." } */
 }
index 048a95d6dcffc340f899748b6c399d380e750499..b837ad0c36cf1cd8a03eaf2c4a5ae7000314094c 100644 (file)
@@ -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]" } */
 }
 
index 389afaf045dc99cb689cddb5ce25eb6da39777ef..921461a549d61341d254b6034e1fb1e98d040778 100644 (file)
@@ -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]." } */
index 9b5f33317350f4aa804e8e7b240fbee22590f761..02dac6522114a9b33ef0e0089ae06442e873da4a 100644 (file)
@@ -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]." } */
 }
index 729ad45d6ac2074579665fc44a61d008a80a599f..c7217ad4f7b8eeb47dd8114b3939a8288c209f6b 100644 (file)
@@ -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.
index 80db314b3933c450b2859c43115c2d097cdd0e22..591cca28d27efc890ba044a140dc28f710c80679 100644 (file)
@@ -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.
index 849457e559ffe0bee850c245539f4a162bad9348..616145b65a61a1414363583df44ddde64be599a9 100644 (file)
@@ -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));
index a3fc91882113a0caea87fca458ab1297e325210d..530e2c564528193be971a13fed8bd259c9e5a57c 100644 (file)
@@ -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);
 
index c61891f5c078ed0ec16ff9c073268554f241fc12..6ab3398c762d908556884bb9f7f2c94e9194eb2f 100644 (file)
@@ -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]);
index 5a95577412473c23e8c788c78a2dd4d97ea270f5..80503f8d217e7e173893f5f7619ece75d8739da9 100644 (file)
@@ -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 (file)
index 0000000..6487613
--- /dev/null
@@ -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 (file)
index 0000000..73c335f
--- /dev/null
@@ -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 (file)
index 0000000..b44ac9d
--- /dev/null
@@ -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);
+}
index a1b103918cff509d241217875d74e3a7a9e3678e..d9ca3447eb963c24ea460f89b6d7177cbf67cc89 100644 (file)
@@ -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" }
 }
index 9bfc84af5697f4a4ee0e7609dab66841a49fb445..6412874e2f958859f9459c67ad4558bb54de3dcf 100644 (file)
@@ -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);
 }
 
index 7601679fac3d63100ec9f3f52518552d251c3c9a..93c54c646c069f0d466003241f201b49dad31b65 100644 (file)
@@ -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" }
 }