gcc version 3.4.2 [FreeBSD] 20040728
# c++filt _Z4test1AILZ2buEE
Segmentation fault (core dumped)

gcc version 3.2
# c++filt _Z4test1AILZ2buEE
test(A<bu>)

Quick workaround patch based on 3.2 libiberty sources.
(similar to be done over libiberty demangler)

Index: cp-demangle.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc/cp-demangle.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 cp-demangle.c
--- cp-demangle.c       28 Jul 2004 03:11:34 -0000      1.1.1.5
+++ cp-demangle.c       31 Jan 2005 21:03:22 -0000
@@ -2242,6 +2242,47 @@
   return al;
 }
 
+static struct demangle_component *
+d_literal (di)
+     struct d_info *di;
+{
+  struct demangle_component *type;
+  enum demangle_component_type t;
+  const char *s;
+
+  type = cplus_demangle_type (di);
+
+  /* If we have a type we know how to print, we aren't going to
+     print the type name itself.  */
+  if (type->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
+      && type->u.s_builtin.type->print != D_PRINT_DEFAULT)
+    di->expansion -= type->u.s_builtin.type->len;
+
+  /* Rather than try to interpret the literal value, we just
+     collect it as a string.  Note that it's possible to have a
+     floating point literal here.  The ABI specifies that the
+     format of such literals is machine independent.  That's fine,
+     but what's not fine is that versions of g++ up to 3.2 with
+     -fabi-version=1 used upper case letters in the hex constant,
+     and dumped out gcc's internal representation.  That makes it
+     hard to tell where the constant ends, and hard to dump the
+     constant in any readable form anyhow.  We don't attempt to
+     handle these cases.  */
+
+  t = DEMANGLE_COMPONENT_LITERAL;
+  if (d_peek_char (di) == 'n')
+    {
+      t = DEMANGLE_COMPONENT_LITERAL_NEG;
+      d_advance (di, 1);
+    }
+  s = d_str (di);
+  while (d_peek_char (di) != 'E')
+    d_advance (di, 1);
+  
+  return d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s));
+}
+
+
 /* <template-arg> ::= <type>
                   ::= X <expression> E
                   ::= <expr-primary>
@@ -2263,7 +2304,19 @@
       return ret;
 
     case 'L':
-      return d_expr_primary (di);
+      d_advance (di, 1);
+
+      if(d_peek_char(di) == 'Z') {
+        d_advance (di, 1);
+
+       ret = d_encoding(di, 0);
+      } else
+       ret = d_literal(di);
+
+      if (d_next_char (di) != 'E')
+       return NULL;
+
+      return ret;
 
     default:
       return cplus_demangle_type (di);
@@ -2392,41 +2445,8 @@
   if (d_peek_char (di) == '_')
     ret = cplus_demangle_mangled_name (di, 0);
   else
-    {
-      struct demangle_component *type;
-      enum demangle_component_type t;
-      const char *s;
-
-      type = cplus_demangle_type (di);
-
-      /* If we have a type we know how to print, we aren't going to
-        print the type name itself.  */
-      if (type->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
-         && type->u.s_builtin.type->print != D_PRINT_DEFAULT)
-       di->expansion -= type->u.s_builtin.type->len;
-
-      /* Rather than try to interpret the literal value, we just
-        collect it as a string.  Note that it's possible to have a
-        floating point literal here.  The ABI specifies that the
-        format of such literals is machine independent.  That's fine,
-        but what's not fine is that versions of g++ up to 3.2 with
-        -fabi-version=1 used upper case letters in the hex constant,
-        and dumped out gcc's internal representation.  That makes it
-        hard to tell where the constant ends, and hard to dump the
-        constant in any readable form anyhow.  We don't attempt to
-        handle these cases.  */
-
-      t = DEMANGLE_COMPONENT_LITERAL;
-      if (d_peek_char (di) == 'n')
-       {
-         t = DEMANGLE_COMPONENT_LITERAL_NEG;
-         d_advance (di, 1);
-       }
-      s = d_str (di);
-      while (d_peek_char (di) != 'E')
-       d_advance (di, 1);
-      ret = d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s));
-    }
+    ret = d_literal(di);
+  
   if (d_next_char (di) != 'E')
     return NULL;
   return ret;

-- 
           Summary: segfault in cp-demangle
           Product: gcc
           Version: 3.4.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: other
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: unicorn at freeshell dot org
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i386-unknown-freebsd5.3
  GCC host triplet: i386-unknown-freebsd5.3
GCC target triplet: i386-unknown-freebsd5.3


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19730

Reply via email to