This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java 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]

Patch: fix PR 6388


This patch fixes PR 6388.

This is a rewrite of a patch I sent before:

    http://gcc.gnu.org/ml/java-patches/2002-q2/msg00409.html

In his response to that one, rth pointed out some other problems in
the surrounding code.  This patch attempts to fix those as well.

There didn't seem to be a way to sign-extend an int constant, hence
the code in the patch to do this by hand.

I'll check in the test case for this in a bit.

Ok?

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	Fix for PR java/6388.
	* lex.h (JAVA_INTEGRAL_RANGE_ERROR): Wrap in do...while.
	* java-tree.h (enum java_tree_index): New values
	JTI_DECIMAL_INT_RANGE_TYPE_NODE,
	JTI_DECIMAL_LONG_RANGE_TYPE_NODE.
	(decimal_int_range_type): New define.
	(decimal_long_range_type): Likewise.
	* lex.c (yylex): Rewrote range checking.  Sign extend literals.
	* decl.c (java_init_decl_processing): Initialize
	decimal_int_range_type and decimal_long_range_type.

Index: decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/decl.c,v
retrieving revision 1.132
diff -u -r1.132 decl.c
--- decl.c 21 Sep 2002 02:19:44 -0000 1.132
+++ decl.c 23 Oct 2002 22:49:18 -0000
@@ -1,6 +1,6 @@
 /* Process declarations and variables for the GNU compiler for the
    Java(TM) language.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
 This file is part of GNU CC.
@@ -453,6 +453,13 @@
   integer_two_node = build_int_2 (2, 0);
   integer_four_node = build_int_2 (4, 0);
   integer_minus_one_node = build_int_2 (-1, -1);
+
+  /* A couple types used for handling range checking in the lexer.  */
+  decimal_int_range_type = build_index_type (build_int_2 (0x80000000, 0));
+  decimal_long_range_type
+    = build_index_type (HOST_BITS_PER_WIDE_INT == 32
+			? build_int_2 (0, 0x80000000)
+			: build_int_2 (0x8000000000000000, 0));
 
   size_zero_node = size_int (0);
   size_one_node = size_int (1);
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.158
diff -u -r1.158 java-tree.h
--- java-tree.h 15 Oct 2002 15:29:12 -0000 1.158
+++ java-tree.h 23 Oct 2002 22:49:19 -0000
@@ -275,6 +275,9 @@
   JTI_UNSIGNED_INT_TYPE_NODE,
   JTI_UNSIGNED_LONG_TYPE_NODE,
   
+  JTI_DECIMAL_INT_RANGE_TYPE_NODE,
+  JTI_DECIMAL_LONG_RANGE_TYPE_NODE,
+
   JTI_BOOLEAN_TYPE_NODE,
 
   JTI_OBJECT_TYPE_NODE,
@@ -440,6 +443,11 @@
   java_global_trees[JTI_UNSIGNED_INT_TYPE_NODE]
 #define unsigned_long_type_node \
   java_global_trees[JTI_UNSIGNED_LONG_TYPE_NODE]
+
+#define decimal_int_range_type \
+  java_global_trees[JTI_DECIMAL_INT_RANGE_TYPE_NODE]
+#define decimal_long_range_type \
+  java_global_trees[JTI_DECIMAL_LONG_RANGE_TYPE_NODE]
 
 #define boolean_type_node \
   java_global_trees[JTI_BOOLEAN_TYPE_NODE]
Index: lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lex.c,v
retrieving revision 1.92
diff -u -r1.92 lex.c
--- lex.c 30 Sep 2002 14:57:43 -0000 1.92
+++ lex.c 23 Oct 2002 22:49:21 -0000
@@ -995,7 +995,8 @@
       int  i;
 #ifndef JC1_LITE
       int  number_beginning = ctxp->c_line->current;
-      tree value;
+      int  valbits;
+      tree value, range;
 #endif
       
       /* We might have a . separator instead of a FP like .[0-9]*.  */
@@ -1218,32 +1219,58 @@
 	}
       /* End borrowed section.  */
 
+#ifndef JC1_LITE
       /* Range checking.  */
       if (long_suffix)
+	range = (radix == 10 ? decimal_long_range_type
+		 : unsigned_long_type_node);
+      else
+	range = (radix == 10 ? decimal_int_range_type
+		 : unsigned_int_type_node);
+
+      value = build_int_2 (low, high);
+      /* Temporarily set type for int_fits_type_p.  Must be unsigned.  */
+      TREE_TYPE (value) = unsigned_long_type_node;
+
+      if (! int_fits_type_p (value, range))
 	{
-	  /* 9223372036854775808L is valid if operand of a '-'. Otherwise
-	     9223372036854775807L is the biggest `long' literal that can be
-	     expressed using a 10 radix. For other radices, everything that
-	     fits withing 64 bits is OK.  */
-	  int hb = (high >> 31);
-	  if (overflow || (hb && low && radix == 10)
-	      || (hb && high & 0x7fffffff && radix == 10))
+	  if (long_suffix)
 	    JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `long' literal");
+	  else
+	    JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `int' literal");
+	}
+
+      /* Sign extend if required.  */
+      valbits = long_suffix ? 64 : 32;
+      if (HOST_BITS_PER_WIDE_INT >= valbits)
+	{
+	  unsigned HOST_WIDE_INT sign = (low >> (valbits - 1)) & 1;
+	  high = sign ? -1 : 0;
+	  if (sign && HOST_BITS_PER_WIDE_INT > valbits)
+	    {
+	      HOST_WIDE_INT mask = ((HOST_WIDE_INT) 1 << valbits) - 1;
+	      low |= ~mask;
+	    }
+	}
+      else if (2 * HOST_BITS_PER_WIDE_INT >= valbits)
+	{
+	  unsigned HOST_WIDE_INT sign;
+	  valbits -= HOST_BITS_PER_WIDE_INT;
+	  sign = (high >> (valbits - 1)) & 1;
+	  if (sign && HOST_BITS_PER_WIDE_INT > valbits)
+	    {
+	      HOST_WIDE_INT mask = ((HOST_WIDE_INT) 1 << valbits) - 1;
+	      high |= ~mask;
+	    }
 	}
       else
 	{
-	  /* 2147483648 is valid if operand of a '-'. Otherwise,
-	     2147483647 is the biggest `int' literal that can be
-	     expressed using a 10 radix. For other radices, everything
-	     that fits within 32 bits is OK.  As all literals are
-	     signed, we sign extend here.  */
-	  int hb = (low >> 31) & 0x1;
-	  if (overflow || high || (hb && low & 0x7fffffff && radix == 10))
-	    JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `int' literal");
-	  high = -hb;
+	  /* We need more than 2 words to represent.  */
+	  abort ();
 	}
-#ifndef JC1_LITE
+
       value = build_int_2 (low, high);
+
       JAVA_RADIX10_FLAG (value) = radix == 10;
       SET_LVAL_NODE_TYPE (value, long_suffix ? long_type_node : int_type_node);
 #else
Index: lex.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lex.h,v
retrieving revision 1.26
diff -u -r1.26 lex.h
--- lex.h 21 Oct 2001 21:32:11 -0000 1.26
+++ lex.h 23 Oct 2002 22:49:21 -0000
@@ -1,5 +1,5 @@
 /* Language lexer definitions for the GNU compiler for the Java(TM) language.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
 
 This file is part of GNU CC.
@@ -185,7 +185,7 @@
 #define SET_LVAL_NODE_TYPE(NODE, TYPE)
 #define BUILD_ID_WFL(EXP) (EXP)
 #define JAVA_FLOAT_RANGE_ERROR(S) {}
-#define JAVA_INTEGRAL_RANGE_ERROR(S) {}
+#define JAVA_INTEGRAL_RANGE_ERROR(S) do { } while (0)
 
 #else
 
@@ -237,12 +237,12 @@
     ctxp->c_line->current = i;						  \
   }
 #define JAVA_INTEGRAL_RANGE_ERROR(m)		\
-  {						\
+  do {						\
     int i = ctxp->c_line->current;		\
     ctxp->c_line->current = number_beginning;	\
     java_lex_error (m, 0);			\
     ctxp->c_line->current = i;			\
-  }
+  } while (0)
 
 #endif /* Definitions for jc1 compilation only */
 


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