This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/81908] [8 Regression] FAIL: gfortran.dg/alloc_comp_auto_array_2.f90 -O3 -g -m32
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 21 Aug 2017 09:17:44 +0000
- Subject: [Bug middle-end/81908] [8 Regression] FAIL: gfortran.dg/alloc_comp_auto_array_2.f90 -O3 -g -m32
- Auto-submitted: auto-generated
- References: <bug-81908-4@http.gcc.gnu.org/bugzilla/>
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;
}