This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Sign extension of type with precision of 0 causes fault in force_fit_type
- To: dave at hiauly1 dot hia dot nrc dot ca (John David Anglin)
- Subject: Re: Sign extension of type with precision of 0 causes fault in force_fit_type
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- Date: Fri, 13 Apr 2001 00:08:18 -0400 (EDT)
- Cc: gcc-bugs at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
>
> The following error occured in my latest build under vax ultrix:
>
> /xxx/gnu/gcc-3.0/objdir/gcc/xgcc -B/xxx/gnu/gcc-3.0/objdir/gcc/ -nostdinc++ -L/xxx/gnu/gcc-3.0/objdir/vax-dec-ultrix4.3/libstdc++-v3/src -L/xxx/gnu/gcc-3.0/objdir/vax-dec-ultrix4.3/libstdc++-v3/src/.libs -B/usr/local/vax-dec-ultrix4.3/bin/ -B/usr/local/vax-dec-ultrix4.3/lib/ -isystem /usr/local/vax-dec-ultrix4.3/include -nostdinc++ -I../../../../libstdc++-v3/include -I../../../../libstdc++-v3/include/std -I../../../../libstdc++-v3/include/c_std -I../include -I../../../../libstdc++-v3/libsupc++ -I../libio -I../../../../libstdc++-v3/libio -I../../../../libstdc++-v3/libmath -g -O2 -fno-implicit-templates -Wall -Wno-format -W -Wwrite-strings -Winline -fdiagnostics-show-location=once -g -c limitsMEMBERS.cc -o limitsMEMBERS.o
> In file included from limitsMEMBERS.cc:37:
> ../include/bits/std_limits.h:56: Internal error: Illegal instruction
Here is a patch for review to fix the above problem. The problem
arises because the initial type of each value is changed to enumtype
prior to min_precision being called. The precision of enumtype is
zero at that point. The call to min_precision requires that the
precision for the value be set correctly if the value is negative.
I have revised the code so that the calls to min_precision now
occur before the type of value is changed. I have checked that
it resolves the internal error on the vax and done a complete
bootstrap check with no regressions under i686 linux.
Dave
--
J. David Anglin dave.anglin@nrc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6605)
2001-04-12 John David Anglin <dave@hiauly1.hia.nrc.ca>
* cp/decl.c (finish_enum): Revise calculation of precision needed
for enumeration types.
--- decl.c.orig Thu Apr 12 12:35:11 2001
+++ decl.c Thu Apr 12 17:02:07 2001
@@ -12923,8 +12923,11 @@
finish_enum (enumtype)
tree enumtype;
{
- register tree minnode = NULL_TREE, maxnode = NULL_TREE;
- /* Calculate the maximum value of any enumerator in this type. */
+ unsigned int precision = 1;
+ int unsignedp = 1;
+
+ /* Calculate the maximum precision needed for any enumerator in
+ this type assuming the values are unsigned. */
tree values = TYPE_VALUES (enumtype);
if (values)
@@ -12954,6 +12957,11 @@
value = DECL_INITIAL (decl);
if (value && !processing_template_decl)
{
+ precision = MAX (precision, min_precision (value, 1));
+
+ if (unsignedp && tree_int_cst_sgn (value) < 0)
+ unsignedp = 0;
+
/* Set the TREE_TYPE for the VALUE as well. That's so
that when we call decl_constant_value we get an
entity of the right type (but with the constant
@@ -12962,18 +12970,8 @@
reason to do that when processing_template_decl.
And, if the expression is something like a
TEMPLATE_PARM_INDEX or a CAST_EXPR doing so will
- wreak havoc on the intended type of the expression.
-
- Of course, there's also no point in trying to compute
- minimum or maximum values if we're in a template. */
+ wreak havoc on the intended type of the expression. */
TREE_TYPE (value) = enumtype;
-
- if (!minnode)
- minnode = maxnode = value;
- else if (tree_int_cst_lt (maxnode, value))
- maxnode = value;
- else if (tree_int_cst_lt (value, minnode))
- minnode = value;
}
if (processing_template_decl)
@@ -12987,8 +12985,6 @@
TREE_VALUE (pair) = value;
}
}
- else
- maxnode = minnode = integer_zero_node;
TYPE_VALUES (enumtype) = nreverse (values);
@@ -13000,11 +12996,11 @@
}
else
{
- int unsignedp = tree_int_cst_sgn (minnode) >= 0;
- int lowprec = min_precision (minnode, unsignedp);
- int highprec = min_precision (maxnode, unsignedp);
- int precision = MAX (lowprec, highprec);
tree tem;
+
+ if (!unsignedp)
+ /* Need signed type with one bit more. */
+ precision += 1;
TYPE_SIZE (enumtype) = NULL_TREE;