PR middle-end/86631 - missing -Walloc-size-larger-than on ILP32 hosts
authorMartin Sebor <msebor@redhat.com>
Tue, 28 Aug 2018 19:09:38 +0000 (19:09 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Tue, 28 Aug 2018 19:09:38 +0000 (13:09 -0600)
gcc/ChangeLog:

PR middle-end/86631
* calls.c (alloc_max_size): Treat HOST_WIDE_INT special.
* gimple-ssa-warn-alloca.c (adjusted_warn_limit): New function.
(pass_walloca::gate): Use it.
(alloca_call_type): Same.
(pass_walloca::execute): Same.
* stor-layout.c (layout_decl): Treat HOST_WIDE_INT special.

gcc/testsuite/ChangeLog:

PR middle-end/86631
* g++.dg/Walloca1.C: Adjust.

From-SVN: r263928

gcc/ChangeLog
gcc/calls.c
gcc/gimple-ssa-warn-alloca.c
gcc/stor-layout.c
gcc/testsuite/g++.dg/Walloca1.C

index 3ff21c3..b4b56da 100644 (file)
@@ -1,3 +1,13 @@
+2018-08-28  Martin Sebor  <msebor@redhat.com>
+
+       PR middle-end/86631
+       * calls.c (alloc_max_size): Treat HOST_WIDE_INT special.
+       * gimple-ssa-warn-alloca.c (adjusted_warn_limit): New function.
+       (pass_walloca::gate): Use it.
+       (alloca_call_type): Same.
+       (pass_walloca::execute): Same.
+       * stor-layout.c (layout_decl): Treat HOST_WIDE_INT special.
+
 2018-08-28  David Malcolm  <dmalcolm@redhat.com>
 
        * dumpfile.h (ATTRIBUTE_GCC_DUMP_PRINTF): Change version check on
index 87e3f00..e9660b6 100644 (file)
@@ -1222,8 +1222,11 @@ alloc_max_size (void)
   if (alloc_object_size_limit)
     return alloc_object_size_limit;
 
-  alloc_object_size_limit
-    = build_int_cst (size_type_node, warn_alloc_size_limit);
+  HOST_WIDE_INT limit = warn_alloc_size_limit;
+  if (limit == HOST_WIDE_INT_MAX)
+    limit = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
+
+  alloc_object_size_limit = build_int_cst (size_type_node, limit);
 
   return alloc_object_size_limit;
 }
index 4347707..4d5aed8 100644 (file)
@@ -38,6 +38,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 #include "intl.h"
 
+static unsigned HOST_WIDE_INT adjusted_warn_limit (bool);
+
 const pass_data pass_data_walloca = {
   GIMPLE_PASS,
   "walloca",
@@ -82,7 +84,9 @@ pass_walloca::gate (function *fun ATTRIBUTE_UNUSED)
   // Warning is disabled when its size limit is greater than PTRDIFF_MAX
   // for the target maximum, which makes the limit negative since when
   // represented in signed HOST_WIDE_INT.
-  return warn_alloca_limit >= 0 || warn_vla_limit >= 0;
+  unsigned HOST_WIDE_INT max = tree_to_uhwi (TYPE_MAX_VALUE (ptrdiff_type_node));
+  return (adjusted_warn_limit (false) <= max
+         || adjusted_warn_limit (true) <= max);
 }
 
 // Possible problematic uses of alloca.
@@ -127,6 +131,30 @@ struct alloca_type_and_limit {
   alloca_type_and_limit (enum alloca_type type) : type(type) { }
 };
 
+/* Return the value of the argument N to -Walloca-larger-than= or
+   -Wvla-larger-than= adjusted for the target data model so that
+   when N == HOST_WIDE_INT_MAX, the adjusted value is set to
+   PTRDIFF_MAX on the target.  This is done to prevent warnings
+   for unknown/unbounded allocations in the "permissive mode"
+   while still diagnosing excessive and necessarily invalid
+   allocations.  */
+
+static unsigned HOST_WIDE_INT
+adjusted_warn_limit (bool idx)
+{
+  static HOST_WIDE_INT limits[2];
+  if (limits[idx])
+    return limits[idx];
+
+  limits[idx] = idx ? warn_vla_limit : warn_alloca_limit;
+  if (limits[idx] != HOST_WIDE_INT_MAX)
+    return limits[idx];
+
+  limits[idx] = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
+  return limits[idx];
+}
+
+
 // NOTE: When we get better range info, this entire function becomes
 // irrelevant, as it should be possible to get range info for an SSA
 // name at any point in the program.
@@ -309,11 +337,7 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
 
   // Adjust warn_alloca_max_size for VLAs, by taking the underlying
   // type into account.
-  unsigned HOST_WIDE_INT max_size;
-  if (is_vla)
-    max_size = warn_vla_limit;
-  else
-    max_size = warn_alloca_limit;
+  unsigned HOST_WIDE_INT max_size = adjusted_warn_limit (is_vla);
 
   // Check for the obviously bounded case.
   if (TREE_CODE (len) == INTEGER_CST)
@@ -510,6 +534,8 @@ pass_walloca::execute (function *fun)
          struct alloca_type_and_limit t
            = alloca_call_type (stmt, is_vla, &invalid_casted_type);
 
+         unsigned HOST_WIDE_INT adjusted_alloca_limit
+           = adjusted_warn_limit (false);
          // Even if we think the alloca call is OK, make sure it's not in a
          // loop, except for a VLA, since VLAs are guaranteed to be cleaned
          // up when they go out of scope, including in a loop.
@@ -519,8 +545,7 @@ pass_walloca::execute (function *fun)
                 is less than the maximum valid object size.  */
              const offset_int maxobjsize
                = wi::to_offset (max_object_size ());
-             if ((unsigned HOST_WIDE_INT) warn_alloca_limit
-                 < maxobjsize.to_uhwi ())
+             if (adjusted_alloca_limit < maxobjsize.to_uhwi ())
                t = alloca_type_and_limit (ALLOCA_IN_LOOP);
            }
 
@@ -544,7 +569,8 @@ pass_walloca::execute (function *fun)
                    print_decu (t.limit, buff);
                    inform (loc, G_("limit is %wu bytes, but argument "
                                    "may be as large as %s"),
-                           is_vla ? warn_vla_limit : warn_alloca_limit, buff);
+                           is_vla ? warn_vla_limit : adjusted_alloca_limit,
+                           buff);
                  }
              }
              break;
@@ -559,7 +585,7 @@ pass_walloca::execute (function *fun)
                  {
                    print_decu (t.limit, buff);
                    inform (loc, G_("limit is %wu bytes, but argument is %s"),
-                             is_vla ? warn_vla_limit : warn_alloca_limit,
+                             is_vla ? warn_vla_limit : adjusted_alloca_limit,
                              buff);
                  }
              }
index 85937d0..088f360 100644 (file)
@@ -760,14 +760,19 @@ layout_decl (tree decl, unsigned int known_align)
     {
       tree size = DECL_SIZE_UNIT (decl);
 
-      if (size != 0 && TREE_CODE (size) == INTEGER_CST
-         && compare_tree_int (size, warn_larger_than_size) > 0)
+      if (size != 0 && TREE_CODE (size) == INTEGER_CST)
        {
-         unsigned HOST_WIDE_INT uhwisize = tree_to_uhwi (size);
-
-         warning (OPT_Wlarger_than_, "size of %q+D %wu bytes exceeds "
-                  "maximum object size %wu",
-                  decl, uhwisize, warn_larger_than_size);
+         /* -Wlarger-than= argument of HOST_WIDE_INT_MAX is treated
+            as if PTRDIFF_MAX had been specified, with the value
+            being that on the target rather than the host.  */
+         unsigned HOST_WIDE_INT max_size = warn_larger_than_size;
+         if (max_size == HOST_WIDE_INT_MAX)
+           max_size = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
+
+         if (compare_tree_int (size, max_size) > 0)
+           warning (OPT_Wlarger_than_, "size of %q+D %E bytes exceeds "
+                    "maximum object size %wu",
+                    decl, size, max_size);
        }
     }
 
index b860a42..2985ac9 100644 (file)
@@ -1,7 +1,9 @@
-/* PR middle-end/79809 */
+/* PR middle-end/79809 - ICE in alloca_call_type, at gimple-ssa-warn-alloca.c */
 /* { dg-do compile } */
 /* { dg-options "-Walloca-larger-than=4207115063 -Wvla-larger-than=1233877270 -O2" } */
 /* { dg-require-effective-target alloca } */
 
 int a;
-char *b = static_cast<char *>(__builtin_alloca (a)); // { dg-warning "argument to .alloca. may be too large|unbounded use of" }
+char *b = static_cast<char *>(__builtin_alloca (a));
+
+// { dg-prune-output "argument to .alloca." }