From 07523e7c080b44354836524f09f1c9a11f2a1679 Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Wed, 10 Dec 2008 17:11:44 -0500
Subject: [PATCH] re PR c++/35319 (ICE throwing fixed-point types)

        PR c++/35319
        * mangle.c (write_builtin_type): Add mangling for decimal floating
        point and fixed point types.
        (write_type): Pass FIXED_POINT_TYPE along.
        * cp-demangle.c (cplus_demangle_type): Support fixed-point types.
        (d_print_comp, d_dump): Likewise.

From-SVN: r142661
---
 gcc/cp/ChangeLog                  |  7 ++++
 gcc/cp/mangle.c                   | 54 +++++++++++++++++++++++++++++++
 gcc/testsuite/ChangeLog           |  5 +++
 gcc/testsuite/g++.dg/ext/fixed2.C |  7 ++++
 include/ChangeLog                 |  5 +++
 include/demangle.h                | 13 ++++++++
 libiberty/ChangeLog               |  5 +++
 libiberty/cp-demangle.c           | 32 ++++++++++++++++++
 8 files changed, 128 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/fixed2.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9c27cd04b854..4b33059287f9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2008-12-10  Jason Merrill  <jason@redhat.com>
+
+	PR c++/35319
+	* mangle.c (write_builtin_type): Add mangling for decimal floating 
+	point and fixed point types.
+	(write_type): Pass FIXED_POINT_TYPE along.
+
 2008-12-09  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/37971
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index c0282d8ade51..36b984e32140 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1598,6 +1598,7 @@ write_type (tree type)
 	    case BOOLEAN_TYPE:
 	    case INTEGER_TYPE:  /* Includes wchar_t.  */
 	    case REAL_TYPE:
+	    case FIXED_POINT_TYPE:
 	      {
 		/* If this is a typedef, TYPE may not be one of
 		   the standard builtin type nodes, but an alias of one.  Use
@@ -1852,6 +1853,59 @@ write_builtin_type (tree type)
 	gcc_unreachable ();
       break;
 
+    case FIXED_POINT_TYPE:
+      write_string ("DF");
+      if (GET_MODE_IBIT (TYPE_MODE (type)) > 0)
+	write_unsigned_number (GET_MODE_IBIT (TYPE_MODE (type)));
+      if (type == fract_type_node
+	  || type == sat_fract_type_node
+	  || type == accum_type_node
+	  || type == sat_accum_type_node)
+	write_char ('i');
+      else if (type == unsigned_fract_type_node
+	       || type == sat_unsigned_fract_type_node
+	       || type == unsigned_accum_type_node
+	       || type == sat_unsigned_accum_type_node)
+	write_char ('j');
+      else if (type == short_fract_type_node
+	       || type == sat_short_fract_type_node
+	       || type == short_accum_type_node
+	       || type == sat_short_accum_type_node)
+	write_char ('s');
+      else if (type == unsigned_short_fract_type_node
+	       || type == sat_unsigned_short_fract_type_node
+	       || type == unsigned_short_accum_type_node
+	       || type == sat_unsigned_short_accum_type_node)
+	write_char ('t');
+      else if (type == long_fract_type_node
+	       || type == sat_long_fract_type_node
+	       || type == long_accum_type_node
+	       || type == sat_long_accum_type_node)
+	write_char ('l');
+      else if (type == unsigned_long_fract_type_node
+	       || type == sat_unsigned_long_fract_type_node
+	       || type == unsigned_long_accum_type_node
+	       || type == sat_unsigned_long_accum_type_node)
+	write_char ('m');
+      else if (type == long_long_fract_type_node
+	       || type == sat_long_long_fract_type_node
+	       || type == long_long_accum_type_node
+	       || type == sat_long_long_accum_type_node)
+	write_char ('x');
+      else if (type == unsigned_long_long_fract_type_node
+	       || type == sat_unsigned_long_long_fract_type_node
+	       || type == unsigned_long_long_accum_type_node
+	       || type == sat_unsigned_long_long_accum_type_node)
+	write_char ('y');
+      else
+	sorry ("mangling unknown fixed point type");
+      write_unsigned_number (GET_MODE_FBIT (TYPE_MODE (type)));
+      if (TYPE_SATURATING (type))
+	write_char ('s');
+      else
+	write_char ('n');
+      break;
+
     default:
       gcc_unreachable ();
     }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 659a5bf24e0d..f8a447f32420 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-10  Jason Merrill  <jason@redhat.com>
+
+	PR c++/35319
+	* g++.dg/ext/fixed2.C: New test.
+
 2008-12-10  Daniel Berlin  <dberlin@dberlin.org>
 
 	PR tree-optimization/36792
diff --git a/gcc/testsuite/g++.dg/ext/fixed2.C b/gcc/testsuite/g++.dg/ext/fixed2.C
new file mode 100644
index 000000000000..a4766eb794cf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/fixed2.C
@@ -0,0 +1,7 @@
+// PR c++/35319
+// { dg-options "" }
+
+void foo()
+{
+  throw 0r;
+}
diff --git a/include/ChangeLog b/include/ChangeLog
index 768fb440033e..a07e075f7134 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-10  Jason Merrill  <jason@redhat.com>
+
+	* demangle.h (enum demangle_component_type): Add 
+	DEMANGLE_COMPONENT_FIXED_TYPE.
+
 2008-11-19  Bob Wilson  <bob.wilson@acm.org>
 	
 	* xtensa-config.h (XCHAL_HAVE_MUL16, XCHAL_HAVE_MUL32, XCHAL_HAVE_DIV32)
diff --git a/include/demangle.h b/include/demangle.h
index 0ea639d62ba3..28c69f5e78c4 100644
--- a/include/demangle.h
+++ b/include/demangle.h
@@ -319,6 +319,8 @@ enum demangle_component_type
      and the right subtree is the member type.  CV-qualifiers appear
      on the latter.  */
   DEMANGLE_COMPONENT_PTRMEM_TYPE,
+  /* A fixed-point type.  */
+  DEMANGLE_COMPONENT_FIXED_TYPE,
   /* An argument list.  The left subtree is the current argument, and
      the right subtree is either NULL or another ARGLIST node.  */
   DEMANGLE_COMPONENT_ARGLIST,
@@ -419,6 +421,17 @@ struct demangle_component
       struct demangle_component *name;
     } s_extended_operator;
 
+    /* For DEMANGLE_COMPONENT_FIXED_TYPE.  */
+    struct
+    {
+      /* The length, indicated by a C integer type name.  */
+      struct demangle_component *length;
+      /* _Accum or _Fract?  */
+      short accum;
+      /* Saturating or not?  */
+      short sat;
+    } s_fixed;
+
     /* For DEMANGLE_COMPONENT_CTOR.  */
     struct
     {
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index fd9d30002176..a6721bf906d8 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-10  Jason Merrill  <jason@redhat.com>
+
+	* cp-demangle.c (cplus_demangle_type): Support fixed-point types.
+	(d_print_comp, d_dump): Likewise.
+
 2008-10-22  Daniel Jacobowitz  <dan@codesourcery.com>
 
 	* Makefile.in (CPPFLAGS): Define.
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 3fa5f1f21d3b..de0d9f7610ea 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -621,6 +621,9 @@ d_dump (struct demangle_component *dc, int indent)
     case DEMANGLE_COMPONENT_PTRMEM_TYPE:
       printf ("pointer to member type\n");
       break;
+    case DEMANGLE_COMPONENT_FIXED_TYPE:
+      printf ("fixed-point type\n");
+      break;
     case DEMANGLE_COMPONENT_ARGLIST:
       printf ("argument list\n");
       break;
@@ -2115,6 +2118,19 @@ cplus_demangle_type (struct d_info *di)
 	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
 	  di->expansion += ret->u.s_builtin.type->len;
 	  break;
+
+	case 'F':
+	  /* Fixed point types. DF<int bits><length><fract bits><sat>  */
+	  ret = d_make_empty (di);
+	  ret->type = DEMANGLE_COMPONENT_FIXED_TYPE;
+	  if ((ret->u.s_fixed.accum = IS_DIGIT (d_peek_char (di))))
+	    /* For demangling we don't care about the bits.  */
+	    d_number (di);
+	  ret->u.s_fixed.length = cplus_demangle_type (di);
+	  d_number (di);
+	  peek = d_next_char (di);
+	  ret->u.s_fixed.sat = (peek == 's');
+	  break;
 	}
       break;
 
@@ -3725,6 +3741,22 @@ d_print_comp (struct d_print_info *dpi,
 	return;
       }
 
+    case DEMANGLE_COMPONENT_FIXED_TYPE:
+      if (dc->u.s_fixed.sat)
+	d_append_string (dpi, "_Sat ");
+      /* Don't print "int _Accum".  */
+      if (dc->u.s_fixed.length->u.s_builtin.type
+	  != &cplus_demangle_builtin_types['i'-'a'])
+	{
+	  d_print_comp (dpi, dc->u.s_fixed.length);
+	  d_append_char (dpi, ' ');
+	}
+      if (dc->u.s_fixed.accum)
+	d_append_string (dpi, "_Accum");
+      else
+	d_append_string (dpi, "_Fract");
+      return;
+
     case DEMANGLE_COMPONENT_ARGLIST:
     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
       if (d_left (dc) != NULL)
-- 
GitLab