This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/81908] [8 Regression] FAIL: gfortran.dg/alloc_comp_auto_array_2.f90 -O3 -g -m32


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81908

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Btw, the anti-ranges can be made "signed" by

  /* If we have an unsigned anti-range convert it to the respective
     signed type.  */
  if (range_type == VR_ANTI_RANGE
      && TYPE_UNSIGNED (exptype)
      && wi::les_p (max, min))
    {
      std::swap (max, min);
      min = min + 1;
      max = max - 1;
      range_type = VR_RANGE;
    }

simplifying the anti-range handling to just the signed case.  Then you
run into the same issue in the signed anti-range handling.

      else if (wi::les_p (min - 1, wzero))
        {
          /* EXP is not in a negative-positive range.  That means EXP
             is either negative, or greater than max.  Since negative
             sizes are invalid make the range [MAX + 1, TYPE_MAX].  */
          min = max + 1;
          max = wmaxval;
        }

this has to use wi::lts_p (or les_p (min, 0).

Suggested cleanup (untested):

Index: gcc/calls.c
===================================================================
--- gcc/calls.c (revision 251217)
+++ gcc/calls.c (working copy)
@@ -1279,8 +1279,9 @@ get_size_range (tree exp, tree range[2])
     }

   wide_int min, max;
+  tree exptype = TREE_TYPE (exp);
   enum value_range_type range_type
-    = ((TREE_CODE (exp) == SSA_NAME && INTEGRAL_TYPE_P (TREE_TYPE (exp)))
+    = ((TREE_CODE (exp) == SSA_NAME && INTEGRAL_TYPE_P (exptype))
        ? get_range_info (exp, &min, &max) : VR_VARYING);

   if (range_type == VR_VARYING)
@@ -1291,49 +1292,40 @@ get_size_range (tree exp, tree range[2])
       return false;
     }

-  tree exptype = TREE_TYPE (exp);
-  unsigned expprec = TYPE_PRECISION (exptype);
-  wide_int wzero = wi::zero (expprec);
-  wide_int wmaxval = wide_int (TYPE_MAX_VALUE (exptype));
-
-  bool signed_p = !TYPE_UNSIGNED (exptype);
+  /* If we have an unsigned anti-range convert it to the respective
+     signed type.  */
+  if (range_type == VR_ANTI_RANGE
+      && TYPE_UNSIGNED (exptype)
+      && wi::les_p (max, min))
+    {
+      std::swap (max, min);
+      min = min + 1;
+      max = max - 1;
+      range_type = VR_RANGE;
+    }

   if (range_type == VR_ANTI_RANGE)
     {
-      if (signed_p)
+      unsigned expprec = TYPE_PRECISION (exptype);
+      wide_int wzero = wi::zero (expprec);
+      wide_int wmaxval = wi::max_value (expprec, TYPE_SIGN (exptype));
+
+      if (wi::lts_p (max, wzero))
        {
-         if (wi::les_p (max, wzero))
-           {
-             /* EXP is not in a strictly negative range.  That means
-                it must be in some (not necessarily strictly) positive
-                range which includes zero.  Since in signed to unsigned
-                conversions negative values end up converted to large
-                positive values, and otherwise they are not valid sizes,
-                the resulting range is in both cases [0, TYPE_MAX].  */
-             min = wzero;
-             max = wmaxval;
-           }
-         else if (wi::les_p (min - 1, wzero))
-           {
-             /* EXP is not in a negative-positive range.  That means EXP
-                is either negative, or greater than max.  Since negative
-                sizes are invalid make the range [MAX + 1, TYPE_MAX].  */
-             min = max + 1;
-             max = wmaxval;
-           }
-         else
-           {
-             max = min - 1;
-             min = wzero;
-           }
+         /* EXP is not in a strictly negative range.  That means
+            it must be in some (not necessarily strictly) positive
+            range which includes zero.  Since in signed to unsigned
+            conversions negative values end up converted to large
+            positive values, and otherwise they are not valid sizes,
+            the resulting range is in both cases [0, TYPE_MAX].  */
+         min = wzero;
+         max = wmaxval;
        }
-      else if (wi::eq_p (wzero, min - 1))
+      else if (wi::les_p (min, wzero))
        {
-         /* EXP is unsigned and not in the range [1, MAX].  That means
-            it's either zero or greater than MAX.  Even though 0 would
-            normally be detected by -Walloc-zero set the range to
-            [MAX, TYPE_MAX] so that when MAX is greater than the limit
-            the whole range is diagnosed.  */
+         /* EXP is not in a negative-positive range.  That means EXP
+            is either negative, or greater than max.  Since negative
+            sizes are invalid make the range [MAX + 1, TYPE_MAX].  */
          min = max + 1;
          max = wmaxval;
        }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]