Sign extension of type with precision of 0 causes fault in force_fit_type

John David Anglin dave@hiauly1.hia.nrc.ca
Thu Apr 12 21:08:00 GMT 2001


> 
> 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;
 



More information about the Gcc-bugs mailing list