Valgrind: r16302 - in /trunk: ./ auxprogs/ coregrind/ coregrind/m_demangle/

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Valgrind: r16302 - in /trunk: ./ auxprogs/ coregrind/ coregrind/m_demangle/

svn-2
Author: mjw
Date: Wed Apr 12 14:01:29 2017
New Revision: 16302

Log:
Update libiberty demangler.

Update the libiberty demangler using the auxprogs/update-demangler
script to the gcc svn r246502 revision. Replaces our rust demangling
with the upstream variant (which is basically the same code in a
separate file). Adds handling of inheriting constructor. Handle
noexcept and throw-spec. Demangle Dc as decltype(auto). And various
(crasher) bug fixes.

Bug 378673.

Added:
    trunk/coregrind/m_demangle/rust-demangle.c
Modified:
    trunk/NEWS
    trunk/auxprogs/update-demangler
    trunk/coregrind/Makefile.am
    trunk/coregrind/m_demangle/ansidecl.h
    trunk/coregrind/m_demangle/cp-demangle.c
    trunk/coregrind/m_demangle/cp-demangle.h
    trunk/coregrind/m_demangle/cplus-dem.c
    trunk/coregrind/m_demangle/d-demangle.c
    trunk/coregrind/m_demangle/demangle.c
    trunk/coregrind/m_demangle/demangle.h
    trunk/coregrind/m_demangle/dyn-string.c
    trunk/coregrind/m_demangle/dyn-string.h
    trunk/coregrind/m_demangle/safe-ctype.c
    trunk/coregrind/m_demangle/safe-ctype.h

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Wed Apr 12 14:01:29 2017
@@ -155,6 +155,7 @@
 377717  Fix massive space leak when reading compressed debuginfo sections
 377930  fcntl syscall wrapper is missing flock structure check
 378535  Valgrind reports INTERNAL ERROR in execve syscall wrapper
+378673  Update libiberty demangler
 
 Release 3.12.0 (20 October 2016)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Modified: trunk/auxprogs/update-demangler
==============================================================================
--- trunk/auxprogs/update-demangler (original)
+++ trunk/auxprogs/update-demangler Wed Apr 12 14:01:29 2017
@@ -17,8 +17,8 @@
 #---------------------------------------------------------------------
 
 # You need to modify these revision numbers for your update.
-old_gcc_revision=r212125  # the revision of the previous update
-new_gcc_revision=r240068  # the revision for this update
+old_gcc_revision=r240068  # the revision of the previous update
+new_gcc_revision=r246502  # the revision for this update
 
 # Unless the organization of demangler related files has changed, no
 # changes below this line should be necessary.
@@ -56,6 +56,7 @@
 cp    ../gcc-$old_gcc_revision/libiberty/cplus-dem.c .
 cp    ../gcc-$old_gcc_revision/libiberty/dyn-string.c .
 cp    ../gcc-$old_gcc_revision/libiberty/d-demangle.c .
+cp    ../gcc-$old_gcc_revision/libiberty/rust-demangle.c .
 cp    ../gcc-$old_gcc_revision/libiberty/safe-ctype.c .
 cd ..
 
@@ -83,6 +84,7 @@
 cp    ../gcc-$new_gcc_revision/libiberty/cplus-dem.c .
 cp    ../gcc-$new_gcc_revision/libiberty/dyn-string.c .
 cp    ../gcc-$new_gcc_revision/libiberty/d-demangle.c .
+cp    ../gcc-$new_gcc_revision/libiberty/rust-demangle.c .
 cp    ../gcc-$new_gcc_revision/libiberty/safe-ctype.c .
 cd ..
 

Modified: trunk/coregrind/Makefile.am
==============================================================================
--- trunk/coregrind/Makefile.am (original)
+++ trunk/coregrind/Makefile.am Wed Apr 12 14:01:29 2017
@@ -362,6 +362,7 @@
  m_demangle/demangle.c \
  m_demangle/dyn-string.c \
  m_demangle/d-demangle.c \
+ m_demangle/rust-demangle.c \
  m_demangle/safe-ctype.c \
  m_dispatch/dispatch-x86-linux.S \
  m_dispatch/dispatch-amd64-linux.S \

Modified: trunk/coregrind/m_demangle/ansidecl.h
==============================================================================
--- trunk/coregrind/m_demangle/ansidecl.h (original)
+++ trunk/coregrind/m_demangle/ansidecl.h Wed Apr 12 14:01:29 2017
@@ -1,5 +1,5 @@
 /* ANSI and traditional C compatability macros
-   Copyright (C) 1991-2015 Free Software Foundation, Inc.
+   Copyright (C) 1991-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
 This program is free software; you can redistribute it and/or modify
@@ -313,13 +313,39 @@
 #define ENUM_BITFIELD(TYPE) unsigned int
 #endif
 
-    /* This is used to mark a class or virtual function as final.  */
-#if __cplusplus >= 201103L
-#define GCC_FINAL final
+/* C++11 adds the ability to add "override" after an implementation of a
+   virtual function in a subclass, to:
+     (A) document that this is an override of a virtual function
+     (B) allow the compiler to issue a warning if it isn't (e.g. a mismatch
+         of the type signature).
+
+   Similarly, it allows us to add a "final" to indicate that no subclass
+   may subsequently override the vfunc.
+
+   Provide OVERRIDE and FINAL as macros, allowing us to get these benefits
+   when compiling with C++11 support, but without requiring C++11.
+
+   For gcc, use "-std=c++11" to enable C++11 support; gcc 6 onwards enables
+   this by default (actually GNU++14).  */
+
+#if __cplusplus >= 201103
+/* C++11 claims to be available: use it.  final/override were only
+   implemented in 4.7, though.  */
+# if GCC_VERSION < 4007
+#  define OVERRIDE
+#  define FINAL
+# else
+#  define OVERRIDE override
+#  define FINAL final
+# endif
 #elif GCC_VERSION >= 4007
-#define GCC_FINAL __final
+/* G++ 4.7 supports __final in C++98.  */
+# define OVERRIDE
+# define FINAL __final
 #else
-#define GCC_FINAL
+/* No C++11 support; leave the macros empty: */
+# define OVERRIDE
+# define FINAL
 #endif
 
 #ifdef __cplusplus

Modified: trunk/coregrind/m_demangle/cp-demangle.c
==============================================================================
--- trunk/coregrind/m_demangle/cp-demangle.c (original)
+++ trunk/coregrind/m_demangle/cp-demangle.c Wed Apr 12 14:01:29 2017
@@ -1,6 +1,5 @@
 /* Demangler for g++ V3 ABI.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <[hidden email]>.
 
    This file is part of the libiberty library, which is part of GCC.
@@ -190,10 +189,10 @@
 static struct demangle_component *d_type (struct d_info *);
 
 #define cplus_demangle_print d_print
-static char *d_print (int, const struct demangle_component *, int, size_t *);
+static char *d_print (int, struct demangle_component *, int, size_t *);
 
 #define cplus_demangle_print_callback d_print_callback
-static int d_print_callback (int, const struct demangle_component *,
+static int d_print_callback (int, struct demangle_component *,
                              demangle_callbackref, void *);
 
 #define cplus_demangle_init_info d_init_info
@@ -282,7 +281,7 @@
      in which they appeared in the mangled string.  */
   struct d_print_mod *next;
   /* The modifier.  */
-  const struct demangle_component *mod;
+  struct demangle_component *mod;
   /* Whether this modifier was printed.  */
   int printed;
   /* The list of templates which applies to this modifier.  */
@@ -360,6 +359,9 @@
   struct d_print_mod *modifiers;
   /* Set to 1 if we saw a demangling error.  */
   int demangle_failure;
+  /* Non-zero if we're printing a lambda argument.  A template
+     parameter reference actually means 'auto'.  */
+  int is_lambda_arg;
   /* The current index into any template argument packs we are using
      for printing, or -1 to print the whole pack.  */
   int pack_index;
@@ -453,6 +455,8 @@
 
 static struct demangle_component *d_special_name (struct d_info *);
 
+static struct demangle_component *d_parmlist (struct d_info *);
+
 static int d_call_offset (struct d_info *, int);
 
 static struct demangle_component *d_ctor_dtor_name (struct d_info *);
@@ -543,7 +547,7 @@
 static inline char d_last_char (struct d_print_info *);
 
 static void
-d_print_comp (struct d_print_info *, int, const struct demangle_component *);
+d_print_comp (struct d_print_info *, int, struct demangle_component *);
 
 static void
 d_print_java_identifier (struct d_print_info *, const char *, int);
@@ -552,30 +556,56 @@
 d_print_mod_list (struct d_print_info *, int, struct d_print_mod *, int);
 
 static void
-d_print_mod (struct d_print_info *, int, const struct demangle_component *);
+d_print_mod (struct d_print_info *, int, struct demangle_component *);
 
 static void
 d_print_function_type (struct d_print_info *, int,
-                       const struct demangle_component *,
+                       struct demangle_component *,
                        struct d_print_mod *);
 
 static void
 d_print_array_type (struct d_print_info *, int,
-                    const struct demangle_component *,
+                    struct demangle_component *,
                     struct d_print_mod *);
 
 static void
-d_print_expr_op (struct d_print_info *, int, const struct demangle_component *);
+d_print_expr_op (struct d_print_info *, int, struct demangle_component *);
 
 static void d_print_cast (struct d_print_info *, int,
-  const struct demangle_component *);
+  struct demangle_component *);
 static void d_print_conversion (struct d_print_info *, int,
- const struct demangle_component *);
+ struct demangle_component *);
 
 static int d_demangle_callback (const char *, int,
                                 demangle_callbackref, void *);
 static char *d_demangle (const char *, int, size_t *);
 
+/* True iff TYPE is a demangling component representing a
+   function-type-qualifier.  */
+
+static int
+is_fnqual_component_type (enum demangle_component_type type)
+{
+  return (type == DEMANGLE_COMPONENT_RESTRICT_THIS
+  || type == DEMANGLE_COMPONENT_VOLATILE_THIS
+  || type == DEMANGLE_COMPONENT_CONST_THIS
+  || type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS
+  || type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
+  || type == DEMANGLE_COMPONENT_NOEXCEPT
+  || type == DEMANGLE_COMPONENT_THROW_SPEC
+  || type == DEMANGLE_COMPONENT_REFERENCE_THIS);
+}
+
+#define FNQUAL_COMPONENT_CASE \
+    case DEMANGLE_COMPONENT_RESTRICT_THIS: \
+    case DEMANGLE_COMPONENT_VOLATILE_THIS: \
+    case DEMANGLE_COMPONENT_CONST_THIS: \
+    case DEMANGLE_COMPONENT_REFERENCE_THIS: \
+    case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: \
+    case DEMANGLE_COMPONENT_TRANSACTION_SAFE: \
+    case DEMANGLE_COMPONENT_NOEXCEPT: \
+    case DEMANGLE_COMPONENT_THROW_SPEC
+
 #ifdef CP_DEMANGLE_DEBUG
 
 static void
@@ -841,6 +871,7 @@
 {
   if (p == NULL || s == NULL || len == 0)
     return 0;
+  p->d_printing = 0;
   p->type = DEMANGLE_COMPONENT_NAME;
   p->u.s_name.s = s;
   p->u.s_name.len = len;
@@ -856,6 +887,7 @@
 {
   if (p == NULL || args < 0 || name == NULL)
     return 0;
+  p->d_printing = 0;
   p->type = DEMANGLE_COMPONENT_EXTENDED_OPERATOR;
   p->u.s_extended_operator.args = args;
   p->u.s_extended_operator.name = name;
@@ -875,6 +907,7 @@
       || (int) kind < gnu_v3_complete_object_ctor
       || (int) kind > gnu_v3_object_ctor_group)
     return 0;
+  p->d_printing = 0;
   p->type = DEMANGLE_COMPONENT_CTOR;
   p->u.s_ctor.kind = kind;
   p->u.s_ctor.name = name;
@@ -894,6 +927,7 @@
       || (int) kind < gnu_v3_deleting_dtor
       || (int) kind > gnu_v3_object_dtor_group)
     return 0;
+  p->d_printing = 0;
   p->type = DEMANGLE_COMPONENT_DTOR;
   p->u.s_dtor.kind = kind;
   p->u.s_dtor.name = name;
@@ -910,6 +944,7 @@
   if (di->next_comp >= di->num_comps)
     return NULL;
   p = &di->comps[di->next_comp];
+  p->d_printing = 0;
   ++di->next_comp;
   return p;
 }
@@ -1001,14 +1036,9 @@
     case DEMANGLE_COMPONENT_RESTRICT:
     case DEMANGLE_COMPONENT_VOLATILE:
     case DEMANGLE_COMPONENT_CONST:
-    case DEMANGLE_COMPONENT_RESTRICT_THIS:
-    case DEMANGLE_COMPONENT_VOLATILE_THIS:
-    case DEMANGLE_COMPONENT_CONST_THIS:
-    case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
-    case DEMANGLE_COMPONENT_REFERENCE_THIS:
-    case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
     case DEMANGLE_COMPONENT_ARGLIST:
     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
+    FNQUAL_COMPONENT_CASE:
       break;
 
       /* Other types should not be seen here.  */
@@ -1242,12 +1272,7 @@
       return 0;
     case DEMANGLE_COMPONENT_TEMPLATE:
       return ! is_ctor_dtor_or_conversion (d_left (dc));
-    case DEMANGLE_COMPONENT_RESTRICT_THIS:
-    case DEMANGLE_COMPONENT_VOLATILE_THIS:
-    case DEMANGLE_COMPONENT_CONST_THIS:
-    case DEMANGLE_COMPONENT_REFERENCE_THIS:
-    case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
-    case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+    FNQUAL_COMPONENT_CASE:
       return has_return_type (d_left (dc));
     }
 }
@@ -1304,13 +1329,12 @@
   while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
  || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
  || dc->type == DEMANGLE_COMPONENT_CONST_THIS
- || dc->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
  || dc->type == DEMANGLE_COMPONENT_REFERENCE_THIS
  || dc->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
     dc = d_left (dc);
 
   /* If the top level is a DEMANGLE_COMPONENT_LOCAL_NAME, then
-     there may be CV-qualifiers on its right argument which
+     there may be function-qualifiers on its right argument which
      really apply here; this happens when parsing a class
      which is local to a function.  */
   if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME)
@@ -1318,12 +1342,7 @@
       struct demangle_component *dcr;
 
       dcr = d_right (dc);
-      while (dcr->type == DEMANGLE_COMPONENT_RESTRICT_THIS
-     || dcr->type == DEMANGLE_COMPONENT_VOLATILE_THIS
-     || dcr->type == DEMANGLE_COMPONENT_CONST_THIS
-     || dcr->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
-     || dcr->type == DEMANGLE_COMPONENT_REFERENCE_THIS
-     || dcr->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
+      while (is_fnqual_component_type (dcr->type))
  dcr = d_left (dcr);
       dc->u.s_binary.right = dcr;
     }
@@ -1597,6 +1616,8 @@
     ret = d_source_name (di);
   else if (IS_LOWER (peek))
     {
+      if (peek == 'o' && d_peek_next_char (di) == 'n')
+ d_advance (di, 2);
       ret = d_operator_name (di);
       if (ret != NULL && ret->type == DEMANGLE_COMPONENT_OPERATOR)
  {
@@ -2185,6 +2206,13 @@
     case 'C':
       {
  enum gnu_v3_ctor_kinds kind;
+ int inheriting = 0;
+
+ if (d_peek_next_char (di) == 'I')
+  {
+    inheriting = 1;
+    d_advance (di, 1);
+  }
 
  switch (d_peek_next_char (di))
   {
@@ -2206,7 +2234,12 @@
   default:
     return NULL;
   }
+
  d_advance (di, 2);
+
+ if (inheriting)
+  cplus_demangle_type (di);
+
  return d_make_ctor (di, kind, di->last_name);
       }
 
@@ -2244,6 +2277,24 @@
     }
 }
 
+/* True iff we're looking at an order-insensitive type-qualifier, including
+   function-type-qualifiers.  */
+
+static int
+next_is_type_qual (struct d_info *di)
+{
+  char peek = d_peek_char (di);
+  if (peek == 'r' || peek == 'V' || peek == 'K')
+    return 1;
+  if (peek == 'D')
+    {
+      peek = d_peek_next_char (di);
+      if (peek == 'x' || peek == 'o' || peek == 'O' || peek == 'w')
+ return 1;
+    }
+  return 0;
+}
+
 /* <type> ::= <builtin-type>
           ::= <function-type>
           ::= <class-enum-type>
@@ -2329,9 +2380,7 @@
      __vector, and it treats it as order-sensitive when mangling
      names.  */
 
-  peek = d_peek_char (di);
-  if (peek == 'r' || peek == 'V' || peek == 'K'
-      || (peek == 'D' && d_peek_next_char (di) == 'x'))
+  if (next_is_type_qual (di))
     {
       struct demangle_component **pret;
 
@@ -2366,6 +2415,7 @@
 
   can_subst = 1;
 
+  peek = d_peek_char (di);
   switch (peek)
     {
     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
@@ -2566,7 +2616,11 @@
   /* auto */
   ret = d_make_name (di, "auto", 4);
   break;
-  
+ case 'c':
+  /* decltype(auto) */
+  ret = d_make_name (di, "decltype(auto)", 14);
+  break;
+
  case 'f':
   /* 32-bit decimal floating point */
   ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[26]);
@@ -2653,10 +2707,10 @@
 
   pstart = pret;
   peek = d_peek_char (di);
-  while (peek == 'r' || peek == 'V' || peek == 'K'
- || (peek == 'D' && d_peek_next_char (di) == 'x'))
+  while (next_is_type_qual (di))
     {
       enum demangle_component_type t;
+      struct demangle_component *right = NULL;
 
       d_advance (di, 1);
       if (peek == 'r')
@@ -2682,12 +2736,41 @@
  }
       else
  {
-  t = DEMANGLE_COMPONENT_TRANSACTION_SAFE;
-  di->expansion += sizeof "transaction_safe";
-  d_advance (di, 1);
+  peek = d_next_char (di);
+  if (peek == 'x')
+    {
+      t = DEMANGLE_COMPONENT_TRANSACTION_SAFE;
+      di->expansion += sizeof "transaction_safe";
+    }
+  else if (peek == 'o'
+   || peek == 'O')
+    {
+      t = DEMANGLE_COMPONENT_NOEXCEPT;
+      di->expansion += sizeof "noexcept";
+      if (peek == 'O')
+ {
+  right = d_expression (di);
+  if (right == NULL)
+    return NULL;
+  if (! d_check_char (di, 'E'))
+    return NULL;
+ }
+    }
+  else if (peek == 'w')
+    {
+      t = DEMANGLE_COMPONENT_THROW_SPEC;
+      di->expansion += sizeof "throw";
+      right = d_parmlist (di);
+      if (right == NULL)
+ return NULL;
+      if (! d_check_char (di, 'E'))
+ return NULL;
+    }
+  else
+    return NULL;
  }
 
-      *pret = d_make_comp (di, t, NULL, NULL);
+      *pret = d_make_comp (di, t, NULL, right);
       if (*pret == NULL)
  return NULL;
       pret = &d_left (*pret);
@@ -3362,6 +3445,8 @@
  first = d_expression_1 (di);
  second = d_expression_1 (di);
  third = d_expression_1 (di);
+ if (third == NULL)
+  return NULL;
       }
     else if (code[0] == 'f')
       {
@@ -3369,6 +3454,8 @@
  first = d_operator_name (di);
  second = d_expression_1 (di);
  third = d_expression_1 (di);
+ if (third == NULL)
+  return NULL;
       }
     else if (code[0] == 'n')
       {
@@ -3546,7 +3633,11 @@
     }
 }
 
-/* <discriminator> ::= _ <(non-negative) number>
+/* <discriminator> ::= _ <number>    # when number < 10
+                   ::= __ <number> _ # when number >= 10
+
+   <discriminator> ::= _ <number>    # when number >=10
+   is also accepted to support gcc versions that wrongly mangled that way.
 
    We demangle the discriminator, but we don't print it out.  FIXME:
    We should print it out in verbose mode.  */
@@ -3554,14 +3645,28 @@
 static int
 d_discriminator (struct d_info *di)
 {
-  int discrim;
+  int discrim, num_underscores = 1;
 
   if (d_peek_char (di) != '_')
     return 1;
   d_advance (di, 1);
+  if (d_peek_char (di) == '_')
+    {
+      ++num_underscores;
+      d_advance (di, 1);
+    }
+
   discrim = d_number (di);
   if (discrim < 0)
     return 0;
+  if (num_underscores > 1 && discrim >= 10)
+    {
+      if (d_peek_char (di) == '_')
+ d_advance (di, 1);
+      else
+ return 0;
+    }
+
   return 1;
 }
 
@@ -3978,6 +4083,8 @@
     case DEMANGLE_COMPONENT_REFERENCE_THIS:
     case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
     case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+    case DEMANGLE_COMPONENT_NOEXCEPT:
+    case DEMANGLE_COMPONENT_THROW_SPEC:
     case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
     case DEMANGLE_COMPONENT_POINTER:
     case DEMANGLE_COMPONENT_COMPLEX:
@@ -4067,6 +4174,7 @@
   dpi->opaque = opaque;
 
   dpi->demangle_failure = 0;
+  dpi->is_lambda_arg = 0;
 
   dpi->component_stack = NULL;
 
@@ -4163,7 +4271,7 @@
 CP_STATIC_IF_GLIBCPP_V3
 int
 cplus_demangle_print_callback (int options,
-                               const struct demangle_component *dc,
+                               struct demangle_component *dc,
                                demangle_callbackref callback, void *opaque)
 {
   struct d_print_info dpi;
@@ -4222,7 +4330,7 @@
 
 CP_STATIC_IF_GLIBCPP_V3
 char *
-cplus_demangle_print (int options, const struct demangle_component *dc,
+cplus_demangle_print (int options, struct demangle_component *dc,
                       int estimate, size_t *palc)
 {
   struct d_growable_string dgs;
@@ -4382,7 +4490,7 @@
 
 static void
 d_print_subexpr (struct d_print_info *dpi, int options,
- const struct demangle_component *dc)
+ struct demangle_component *dc)
 {
   int simple = 0;
   if (dc->type == DEMANGLE_COMPONENT_NAME
@@ -4458,9 +4566,9 @@
 
 static int
 d_maybe_print_fold_expression (struct d_print_info *dpi, int options,
-       const struct demangle_component *dc)
+       struct demangle_component *dc)
 {
-  const struct demangle_component *ops, *operator_, *op1, *op2;
+  struct demangle_component *ops, *operator_, *op1, *op2;
   int save_idx;
 
   const char *fold_code = d_left (dc)->u.s_operator.op->code;
@@ -4521,11 +4629,11 @@
 
 static void
 d_print_comp_inner (struct d_print_info *dpi, int options,
-  const struct demangle_component *dc)
+    struct demangle_component *dc)
 {
   /* Magic variable to let reference smashing skip over the next modifier
      without needing to modify *dc.  */
-  const struct demangle_component *mod_inner = NULL;
+  struct demangle_component *mod_inner = NULL;
 
   /* Variable used to store the current templates while a previously
      captured scope is used.  */
@@ -4608,12 +4716,7 @@
     adpm[i].templates = dpi->templates;
     ++i;
 
-    if (typed_name->type != DEMANGLE_COMPONENT_RESTRICT_THIS
- && typed_name->type != DEMANGLE_COMPONENT_VOLATILE_THIS
- && typed_name->type != DEMANGLE_COMPONENT_CONST_THIS
- && typed_name->type != DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS
- && typed_name->type != DEMANGLE_COMPONENT_TRANSACTION_SAFE
- && typed_name->type != DEMANGLE_COMPONENT_REFERENCE_THIS)
+    if (!is_fnqual_component_type (typed_name->type))
       break;
 
     typed_name = d_left (typed_name);
@@ -4650,13 +4753,7 @@
  d_print_error (dpi);
  return;
       }
-    while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS
-   || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS
-   || local_name->type == DEMANGLE_COMPONENT_CONST_THIS
-   || local_name->type == DEMANGLE_COMPONENT_REFERENCE_THIS
-   || local_name->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
-   || (local_name->type
-       == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS))
+    while (is_fnqual_component_type (local_name->type))
       {
  if (i >= sizeof adpm / sizeof adpm[0])
   {
@@ -4751,33 +4848,41 @@
       }
 
     case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
-      {
- struct d_print_template *hold_dpt;
- struct demangle_component *a = d_lookup_template_argument (dpi, dc);
-
- if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
-  a = d_index_template_argument (a, dpi->pack_index);
+      if (dpi->is_lambda_arg)
+ {
+  /* Show the template parm index, as that's how g++ displays
+     these, and future proofs us against potential
+     '[]<typename T> (T *a, T *b) {...}'.  */
+  d_append_buffer (dpi, "auto:", 5);
+  d_append_num (dpi, dc->u.s_number.number + 1);
+ }
+      else
+ {
+  struct d_print_template *hold_dpt;
+  struct demangle_component *a = d_lookup_template_argument (dpi, dc);
 
- if (a == NULL)
-  {
-    d_print_error (dpi);
-    return;
-  }
+  if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
+    a = d_index_template_argument (a, dpi->pack_index);
 
- /* While processing this parameter, we need to pop the list of
-   templates.  This is because the template parameter may
-   itself be a reference to a parameter of an outer
-   template.  */
+  if (a == NULL)
+    {
+      d_print_error (dpi);
+      return;
+    }
 
- hold_dpt = dpi->templates;
- dpi->templates = hold_dpt->next;
+  /* While processing this parameter, we need to pop the list
+     of templates.  This is because the template parameter may
+     itself be a reference to a parameter of an outer
+     template.  */
 
- d_print_comp (dpi, options, a);
+  hold_dpt = dpi->templates;
+  dpi->templates = hold_dpt->next;
 
- dpi->templates = hold_dpt;
+  d_print_comp (dpi, options, a);
 
- return;
-      }
+  dpi->templates = hold_dpt;
+ }
+      return;
 
     case DEMANGLE_COMPONENT_CTOR:
       d_print_comp (dpi, options, dc->u.s_ctor.name);
@@ -4913,8 +5018,9 @@
     case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
       {
  /* Handle reference smashing: & + && = &.  */
- const struct demangle_component *sub = d_left (dc);
- if (sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
+ struct demangle_component *sub = d_left (dc);
+ if (!dpi->is_lambda_arg
+    && sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
   {
     struct d_saved_scope *scope = d_get_saved_scope (dpi, sub);
     struct demangle_component *a;
@@ -4981,16 +5087,11 @@
       }
       /* Fall through.  */
 
-    case DEMANGLE_COMPONENT_RESTRICT_THIS:
-    case DEMANGLE_COMPONENT_VOLATILE_THIS:
-    case DEMANGLE_COMPONENT_CONST_THIS:
-    case DEMANGLE_COMPONENT_REFERENCE_THIS:
-    case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
     case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
     case DEMANGLE_COMPONENT_POINTER:
     case DEMANGLE_COMPONENT_COMPLEX:
     case DEMANGLE_COMPONENT_IMAGINARY:
-    case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+    FNQUAL_COMPONENT_CASE:
     modifier:
       {
  /* We keep a list of modifiers on the stack.  */
@@ -5589,7 +5690,11 @@
 
     case DEMANGLE_COMPONENT_LAMBDA:
       d_append_string (dpi, "{lambda(");
+      /* Generic lambda auto parms are mangled as the template type
+ parm they are.  */
+      dpi->is_lambda_arg++;
       d_print_comp (dpi, options, dc->u.s_unary_num.sub);
+      dpi->is_lambda_arg--;
       d_append_string (dpi, ")#");
       d_append_num (dpi, dc->u.s_unary_num.num + 1);
       d_append_char (dpi, '}');
@@ -5616,9 +5721,16 @@
 
 static void
 d_print_comp (struct d_print_info *dpi, int options,
-      const struct demangle_component *dc)
+      struct demangle_component *dc)
 {
   struct d_component_stack self;
+  if (dc == NULL || dc->d_printing > 1)
+    {
+      d_print_error (dpi);
+      return;
+    }
+  else
+    dc->d_printing++;
 
   self.dc = dc;
   self.parent = dpi->component_stack;
@@ -5627,6 +5739,7 @@
   d_print_comp_inner (dpi, options, dc);
 
   dpi->component_stack = self.parent;
+  dc->d_printing--;
 }
 
 /* Print a Java dentifier.  For Java we try to handle encoded extended
@@ -5695,13 +5808,7 @@
 
   if (mods->printed
       || (! suffix
-  && (mods->mod->type == DEMANGLE_COMPONENT_RESTRICT_THIS
-      || mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS
-      || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS
-      || mods->mod->type == DEMANGLE_COMPONENT_REFERENCE_THIS
-      || mods->mod->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
-      || (mods->mod->type
-  == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS))))
+  && (is_fnqual_component_type (mods->mod->type))))
     {
       d_print_mod_list (dpi, options, mods->next, suffix);
       return;
@@ -5754,12 +5861,7 @@
   dc = dc->u.s_unary_num.sub;
  }
 
-      while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
-     || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
-     || dc->type == DEMANGLE_COMPONENT_CONST_THIS
-     || dc->type == DEMANGLE_COMPONENT_REFERENCE_THIS
-     || dc->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
-     || dc->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
+      while (is_fnqual_component_type (dc->type))
  dc = d_left (dc);
 
       d_print_comp (dpi, options, dc);
@@ -5779,7 +5881,7 @@
 
 static void
 d_print_mod (struct d_print_info *dpi, int options,
-             const struct demangle_component *mod)
+             struct demangle_component *mod)
 {
   switch (mod->type)
     {
@@ -5798,6 +5900,24 @@
     case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
       d_append_string (dpi, " transaction_safe");
       return;
+    case DEMANGLE_COMPONENT_NOEXCEPT:
+      d_append_string (dpi, " noexcept");
+      if (d_right (mod))
+ {
+  d_append_char (dpi, '(');
+  d_print_comp (dpi, options, d_right (mod));
+  d_append_char (dpi, ')');
+ }
+      return;
+    case DEMANGLE_COMPONENT_THROW_SPEC:
+      d_append_string (dpi, " throw");
+      if (d_right (mod))
+ {
+  d_append_char (dpi, '(');
+  d_print_comp (dpi, options, d_right (mod));
+  d_append_char (dpi, ')');
+ }
+      return;
     case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
       d_append_char (dpi, ' ');
       d_print_comp (dpi, options, d_right (mod));
@@ -5853,7 +5973,7 @@
 
 static void
 d_print_function_type (struct d_print_info *dpi, int options,
-                       const struct demangle_component *dc,
+                       struct demangle_component *dc,
                        struct d_print_mod *mods)
 {
   int need_paren;
@@ -5885,12 +6005,7 @@
   need_space = 1;
   need_paren = 1;
   break;
- case DEMANGLE_COMPONENT_RESTRICT_THIS:
- case DEMANGLE_COMPONENT_VOLATILE_THIS:
- case DEMANGLE_COMPONENT_CONST_THIS:
- case DEMANGLE_COMPONENT_REFERENCE_THIS:
- case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
- case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+ FNQUAL_COMPONENT_CASE:
   break;
  default:
   break;
@@ -5936,7 +6051,7 @@
 
 static void
 d_print_array_type (struct d_print_info *dpi, int options,
-                    const struct demangle_component *dc,
+                    struct demangle_component *dc,
                     struct d_print_mod *mods)
 {
   int need_space;
@@ -5990,7 +6105,7 @@
 
 static void
 d_print_expr_op (struct d_print_info *dpi, int options,
-                 const struct demangle_component *dc)
+                 struct demangle_component *dc)
 {
   if (dc->type == DEMANGLE_COMPONENT_OPERATOR)
     d_append_buffer (dpi, dc->u.s_operator.op->name,
@@ -6003,7 +6118,7 @@
 
 static void
 d_print_cast (struct d_print_info *dpi, int options,
-    const struct demangle_component *dc)
+      struct demangle_component *dc)
 {
   d_print_comp (dpi, options, d_left (dc));
 }
@@ -6012,7 +6127,7 @@
 
 static void
 d_print_conversion (struct d_print_info *dpi, int options,
-    const struct demangle_component *dc)
+    struct demangle_component *dc)
 {
   struct d_print_template dpt;
 
@@ -6451,7 +6566,6 @@
   case DEMANGLE_COMPONENT_CONST_THIS:
   case DEMANGLE_COMPONENT_REFERENCE_THIS:
   case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
-  case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
   default:
     dc = NULL;
     break;

Modified: trunk/coregrind/m_demangle/cp-demangle.h
==============================================================================
--- trunk/coregrind/m_demangle/cp-demangle.h (original)
+++ trunk/coregrind/m_demangle/cp-demangle.h Wed Apr 12 14:01:29 2017
@@ -1,6 +1,5 @@
 /* Internal demangler interface for g++ V3 ABI.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <[hidden email]>.
 
    This file is part of the libiberty library, which is part of GCC.

Modified: trunk/coregrind/m_demangle/cplus-dem.c
==============================================================================
--- trunk/coregrind/m_demangle/cplus-dem.c (original)
+++ trunk/coregrind/m_demangle/cplus-dem.c Wed Apr 12 14:01:29 2017
@@ -1,6 +1,5 @@
 /* Demangler for GNU C++
-   Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1989-2017 Free Software Foundation, Inc.
    Written by James Clark ([hidden email])
    Rewritten by Fred Fish ([hidden email]) for ARM and Lucid demangling
    Modified by Satish Pai ([hidden email]) for HP demangling
@@ -343,6 +342,12 @@
   }
   ,
   {
+    RUST_DEMANGLING_STYLE_STRING,
+    rust_demangling,
+    "Rust style demangling"
+  }
+  ,
+  {
     NULL, unknown_demangling, NULL
   }
 };
@@ -893,10 +898,26 @@
     work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
 
   /* The V3 ABI demangling is implemented elsewhere.  */
-  if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
+  if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING)
     {
       ret = cplus_demangle_v3 (mangled, work->options);
-      if (ret || GNU_V3_DEMANGLING)
+      if (GNU_V3_DEMANGLING)
+ return ret;
+
+      if (ret)
+ {
+  /* Rust symbols are GNU_V3 mangled plus some extra subtitutions.
+     The subtitutions are always smaller, so do in place changes.  */
+  if (rust_is_mangled (ret))
+    rust_demangle_sym (ret);
+  else if (RUST_DEMANGLING)
+    {
+      free (ret);
+      ret = NULL;
+    }
+ }
+
+      if (ret || RUST_DEMANGLING)
  return ret;
     }
 
@@ -922,6 +943,27 @@
   return (ret);
 }
 
+char *
+rust_demangle (const char *mangled, int options)
+{
+  /* Rust symbols are GNU_V3 mangled plus some extra subtitutions.  */
+  char *ret = cplus_demangle_v3 (mangled, options);
+
+  /* The Rust subtitutions are always smaller, so do in place changes.  */
+  if (ret != NULL)
+    {
+      if (rust_is_mangled (ret))
+ rust_demangle_sym (ret);
+      else
+ {
+  free (ret);
+  ret = NULL;
+ }
+    }
+
+  return ret;
+}
+
 /* Demangle ada names.  The encoding is documented in gcc/ada/exp_dbug.ads.  */
 
 char *
@@ -930,7 +972,7 @@
   int len0;
   const char* p;
   char *d;
-  char *demangled;
+  char *demangled = NULL;
   
   /* Discard leading _ada_, which is used for library level subprograms.  */
   if (strncmp (mangled, "_ada_", 5) == 0)
@@ -1175,6 +1217,7 @@
   return demangled;
 
  unknown:
+  XDELETEVEC (demangled);
   len0 = strlen (mangled);
   demangled = XNEWVEC (char, len0 + 3);
 
@@ -1672,12 +1715,13 @@
    0);
       if (!(work->constructor & 1))
  expect_return_type = 1;
-      (*mangled)++;
+      if (!**mangled)
+ success = 0;
+      else
+        (*mangled)++;
       break;
     }
-  else
-    /* fall through */
-    {;}
+  /* fall through */
 
  default:
   if (AUTO_DEMANGLING || GNU_DEMANGLING)
@@ -2153,6 +2197,8 @@
  {
   int idx;
   (*mangled)++;
+  if (**mangled == '\0')
+    return (0);
   (*mangled)++;
 
   idx = consume_count_with_underscores (mangled);
@@ -2997,7 +3043,7 @@
   int success = 1;
   const char *p;
 
-  if ((*mangled)[0] == '_'
+  if ((*mangled)[0] == '_' && (*mangled)[1] != '\0'
       && strchr (cplus_markers, (*mangled)[1]) != NULL
       && (*mangled)[2] == '_')
     {
@@ -3011,7 +3057,7 @@
  && (*mangled)[3] == 't'
  && (*mangled)[4] == '_')
        || ((*mangled)[1] == 'v'
-   && (*mangled)[2] == 't'
+   && (*mangled)[2] == 't' && (*mangled)[3] != '\0'
    && strchr (cplus_markers, (*mangled)[3]) != NULL)))
     {
       /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
@@ -3781,11 +3827,12 @@
     break;
   }
 
- if (*(*mangled)++ != 'F')
+ if (*(*mangled) != 'F')
   {
     success = 0;
     break;
   }
+ (*mangled)++;
       }
     if ((member && !demangle_nested_args (work, mangled, &decl))
  || **mangled != '_')
@@ -4042,6 +4089,7 @@
   success = 0;
   break;
  }
+      /* fall through */
     case 'I':
       (*mangled)++;
       if (**mangled == '_')

Modified: trunk/coregrind/m_demangle/d-demangle.c
==============================================================================
--- trunk/coregrind/m_demangle/d-demangle.c (original)
+++ trunk/coregrind/m_demangle/d-demangle.c Wed Apr 12 14:01:29 2017
@@ -1,5 +1,5 @@
 /* Demangler for the D programming language
-   Copyright 2014, 2015, 2016 Free Software Foundation, Inc.
+   Copyright (C) 2014-2017 Free Software Foundation, Inc.
    Written by Iain Buclaw ([hidden email])
 
 This file is part of the libiberty library.

Modified: trunk/coregrind/m_demangle/demangle.c
==============================================================================
--- trunk/coregrind/m_demangle/demangle.c (original)
+++ trunk/coregrind/m_demangle/demangle.c Wed Apr 12 14:01:29 2017
@@ -43,10 +43,6 @@
 #include "vg_libciface.h"
 #include "demangle.h"
 
-/* fwds */
-static Bool rust_is_mangled ( const HChar* );
-static void rust_demangle_sym ( HChar* );
-
 
 /*------------------------------------------------------------*/
 /*---                                                      ---*/
@@ -408,297 +404,6 @@
 }
 
 
-/*------------------------------------------------------------*/
-/*--- DEMANGLE RUST NAMES                                  ---*/
-/*------------------------------------------------------------*/
-
-/*
- * Mangled Rust symbols look like this:
- *
- *     _$LT$std..sys..fd..FileDesc$u20$as$u20$core..ops..Drop$GT$::drop::hc68340e1baa4987a
- *
- * The original symbol is:
- *
- *     <std::sys::fd::FileDesc as core::ops::Drop>::drop
- *
- * The last component of the path is a 64-bit hash in lowercase hex, prefixed
- * with "h". Rust does not have a global namespace between crates, an illusion
- * which Rust maintains by using the hash to distinguish things that would
- * otherwise have the same symbol.
- *
- * Any path component not starting with a XID_Start character is prefixed with
- * "_".
- *
- * The following escape sequences are used:
- *
- *     ","  =>  $C$
- *     "@"  =>  $SP$
- *     "*"  =>  $BP$
- *     "&"  =>  $RF$
- *     "<"  =>  $LT$
- *     ">"  =>  $GT$
- *     "("  =>  $LP$
- *     ")"  =>  $RP$
- *     " "  =>  $u20$
- *     "\"" =>  $u22$
- *     "'"  =>  $u27$
- *     "+"  =>  $u2b$
- *     ";"  =>  $u3b$
- *     "["  =>  $u5b$
- *     "]"  =>  $u5d$
- *     "{"  =>  $u7b$
- *     "}"  =>  $u7d$
- *     "~"  =>  $u7e$
- *
- * A double ".." means "::" and a single "." means "-".
- *
- * The only characters allowed in the mangled symbol are a-zA-Z0-9 and _.:$
- */
-
-static const HChar *hash_prefix = "::h";
-static const SizeT  hash_prefix_len = 3;
-static const SizeT  hash_len = 16;
-
-static Bool is_prefixed_hash(const HChar *start);
-static Bool looks_like_rust(const HChar *sym, SizeT len);
-static Bool unescape(const HChar **in, HChar **out,
-                     const HChar *seq, HChar value);
-
-/*
- * INPUT:
- *     sym: symbol that has been through BFD-demangling
- *
- * This function looks for the following indicators:
- *
- *  1. The hash must consist of "h" followed by 16 lowercase hex digits.
- *
- *  2. As a sanity check, the hash must use between 5 and 15 of the 16 possible
- *     hex digits. This is true of 99.9998% of hashes so once in your life you
- *     may see a false negative. The point is to notice path components that
- *     could be Rust hashes but are probably not, like "haaaaaaaaaaaaaaaa". In
- *     this case a false positive (non-Rust symbol has an important path
- *     component removed because it looks like a Rust hash) is worse than a
- *     false negative (the rare Rust symbol is not demangled) so this sets the
- *     balance in favor of false negatives.
- *
- *  3. There must be no characters other than a-zA-Z0-9 and _.:$
- *
- *  4. There must be no unrecognized $-sign sequences.
- *
- *  5. There must be no sequence of three or more dots in a row ("...").
- */
-static Bool rust_is_mangled(const HChar *sym)
-{
-   SizeT len, len_without_hash;
-
-   if (!sym)
-      return False;
-
-   len = VG_(strlen)(sym);
-   if (len <= hash_prefix_len + hash_len)
-      /* Not long enough to contain "::h" + hash + something else */
-      return False;
-
-   len_without_hash = len - (hash_prefix_len + hash_len);
-   if (!is_prefixed_hash(sym + len_without_hash))
-      return False;
-
-   return looks_like_rust(sym, len_without_hash);
-}
-
-/*
- * A hash is the prefix "::h" followed by 16 lowercase hex digits. The hex
- * digits must comprise between 5 and 15 (inclusive) distinct digits.
- */
-static Bool is_prefixed_hash(const HChar *str)
-{
-   const HChar *end;
-   Bool seen[16];
-   SizeT i;
-   Int count;
-
-   if (VG_(strncmp)(str, hash_prefix, hash_prefix_len))
-      return False;
-   str += hash_prefix_len;
-
-   VG_(memset)(seen, False, sizeof(seen));
-   for (end = str + hash_len; str < end; str++)
-      if (*str >= '0' && *str <= '9')
-         seen[*str - '0'] = True;
-      else if (*str >= 'a' && *str <= 'f')
-         seen[*str - 'a' + 10] = True;
-      else
-         return False;
-
-   /* Count how many distinct digits seen */
-   count = 0;
-   for (i = 0; i < 16; i++)
-      if (seen[i])
-         count++;
-
-   return count >= 5 && count <= 15;
-}
-
-static Bool looks_like_rust(const HChar *str, SizeT len)
-{
-   const HChar *end = str + len;
-
-   while (str < end) {
-      switch (*str) {
-      case '$':
-         if (!VG_(strncmp)(str, "$C$", 3))
-            str += 3;
-         else if (!VG_(strncmp)(str, "$SP$", 4)
-                  || !VG_(strncmp)(str, "$BP$", 4)
-                  || !VG_(strncmp)(str, "$RF$", 4)
-                  || !VG_(strncmp)(str, "$LT$", 4)
-                  || !VG_(strncmp)(str, "$GT$", 4)
-                  || !VG_(strncmp)(str, "$LP$", 4)
-                  || !VG_(strncmp)(str, "$RP$", 4))
-            str += 4;
-         else if (!VG_(strncmp)(str, "$u20$", 5)
-                  || !VG_(strncmp)(str, "$u22$", 5)
-                  || !VG_(strncmp)(str, "$u27$", 5)
-                  || !VG_(strncmp)(str, "$u2b$", 5)
-                  || !VG_(strncmp)(str, "$u3b$", 5)
-                  || !VG_(strncmp)(str, "$u5b$", 5)
-                  || !VG_(strncmp)(str, "$u5d$", 5)
-                  || !VG_(strncmp)(str, "$u7b$", 5)
-                  || !VG_(strncmp)(str, "$u7d$", 5)
-                  || !VG_(strncmp)(str, "$u7e$", 5))
-            str += 5;
-         else
-            return False;
-         break;
-      case '.':
-         /* Do not allow three or more consecutive dots */
-         if (!VG_(strncmp)(str, "...", 3))
-            return False;
-         /* Fall through */
-      case 'a' ... 'z':
-      case 'A' ... 'Z':
-      case '0' ... '9':
-      case '_':
-      case ':':
-         str++;
-         break;
-      default:
-         return False;
-      }
-   }
-
-   return True;
-}
-
-/*
- * INPUT:
- *     sym: symbol for which rust_is_mangled(sym) returns True
- *
- * The input is demangled in-place because the mangled name is always longer
- * than the demangled one.
- */
-static void rust_demangle_sym(HChar *sym)
-{
-   const HChar *in;
-   HChar *out;
-   const HChar *end;
-
-   if (!sym)
-      return;
-
-   const SizeT  sym_len     = VG_(strlen)(sym);
-   const HChar* never_after = sym + sym_len;
-
-   in = sym;
-   out = sym;
-   end = sym + sym_len - (hash_prefix_len + hash_len);
-
-   while (in < end) {
-      switch (*in) {
-      case '$':
-         if (!(unescape(&in, &out, "$C$", ',')
-               || unescape(&in, &out, "$SP$", '@')
-               || unescape(&in, &out, "$BP$", '*')
-               || unescape(&in, &out, "$RF$", '&')
-               || unescape(&in, &out, "$LT$", '<')
-               || unescape(&in, &out, "$GT$", '>')
-               || unescape(&in, &out, "$LP$", '(')
-               || unescape(&in, &out, "$RP$", ')')
-               || unescape(&in, &out, "$u20$", ' ')
-               || unescape(&in, &out, "$u22$", '\"')
-               || unescape(&in, &out, "$u27$", '\'')
-               || unescape(&in, &out, "$u2b$", '+')
-               || unescape(&in, &out, "$u3b$", ';')
-               || unescape(&in, &out, "$u5b$", '[')
-               || unescape(&in, &out, "$u5d$", ']')
-               || unescape(&in, &out, "$u7b$", '{')
-               || unescape(&in, &out, "$u7d$", '}')
-               || unescape(&in, &out, "$u7e$", '~'))) {
-            goto fail;
-         }
-         break;
-      case '_':
-         /*
-          * If this is the start of a path component and the next
-          * character is an escape sequence, ignore the
-          * underscore. The mangler inserts an underscore to make
-          * sure the path component begins with a XID_Start
-          * character.
-          */
-         if ((in == sym || in[-1] == ':') && in[1] == '$')
-            in++;
-         else
-            *out++ = *in++;
-         break;
-      case '.':
-         if (in[1] == '.') {
-            /* ".." becomes "::" */
-            *out++ = ':';
-            *out++ = ':';
-            in += 2;
-         } else {
-            /* "." becomes "-" */
-            *out++ = '-';
-            in++;
-         }
-         break;
-      case 'a' ... 'z':
-      case 'A' ... 'Z':
-      case '0' ... '9':
-      case ':':
-         *out++ = *in++;
-         break;
-      default:
-         goto fail;
-      }
-   }
-   goto done;
-
-  fail:
-   *out++ = '?'; /* This is pretty lame, but it's hard to do better. */
-  done:
-   *out++ = '\0';
-
-   vg_assert(out <= never_after);
-}
-
-static Bool unescape(const HChar **in, HChar **out,
-                     const HChar *seq, HChar value)
-{
-   SizeT len = VG_(strlen)(seq);
-
-   if (VG_(strncmp)(*in, seq, len))
-      return False;
-
-   **out = value;
-
-   *in += len;
-   *out += 1;
-
-   return True;
-}
-
-
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/

Modified: trunk/coregrind/m_demangle/demangle.h
==============================================================================
--- trunk/coregrind/m_demangle/demangle.h (original)
+++ trunk/coregrind/m_demangle/demangle.h Wed Apr 12 14:01:29 2017
@@ -1,5 +1,5 @@
 /* Defs for interface to demanglers.
-   Copyright (C) 1992-2015 Free Software Foundation, Inc.
+   Copyright (C) 1992-2017 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public License
@@ -65,9 +65,10 @@
 #define DMGL_GNU_V3 (1 << 14)
 #define DMGL_GNAT (1 << 15)
 #define DMGL_DLANG (1 << 16)
+#define DMGL_RUST (1 << 17) /* Rust wraps GNU_V3 style mangling.  */
 
 /* If none of these are set, use 'current_demangling_style' as the default. */
-#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG)
+#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG|DMGL_RUST)
 
 /* Enumeration of possible demangling styles.
 
@@ -90,7 +91,8 @@
   gnu_v3_demangling = DMGL_GNU_V3,
   java_demangling = DMGL_JAVA,
   gnat_demangling = DMGL_GNAT,
-  dlang_demangling = DMGL_DLANG
+  dlang_demangling = DMGL_DLANG,
+  rust_demangling = DMGL_RUST
 } current_demangling_style;
 
 /* Define string names for the various demangling styles. */
@@ -106,6 +108,7 @@
 #define JAVA_DEMANGLING_STYLE_STRING          "java"
 #define GNAT_DEMANGLING_STYLE_STRING          "gnat"
 #define DLANG_DEMANGLING_STYLE_STRING         "dlang"
+#define RUST_DEMANGLING_STYLE_STRING          "rust"
 
 /* Some macros to test what demangling style is active. */
 
@@ -120,6 +123,7 @@
 #define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA)
 #define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT)
 #define DLANG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_DLANG)
+#define RUST_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_RUST)
 
 /* Provide information about the available demangle styles. This code is
    pulled from gdb into libiberty because it is useful to binutils also.  */
@@ -177,6 +181,27 @@
 extern char *
 dlang_demangle (const char *mangled, int options);
 
+/* Returns non-zero iff MANGLED is a rust mangled symbol.  MANGLED must
+   already have been demangled through cplus_demangle_v3.  If this function
+   returns non-zero then MANGLED can be demangled (in-place) using
+   RUST_DEMANGLE_SYM.  */
+extern int
+rust_is_mangled (const char *mangled);
+
+/* Demangles SYM (in-place) if RUST_IS_MANGLED returned non-zero for SYM.
+   If RUST_IS_MANGLED returned zero for SYM then RUST_DEMANGLE_SYM might
+   replace characters that cannot be demangled with '?' and might truncate
+   SYM.  After calling RUST_DEMANGLE_SYM SYM might be shorter, but never
+   larger.  */
+extern void
+rust_demangle_sym (char *sym);
+
+/* Demangles MANGLED if it was GNU_V3 and then RUST mangled, otherwise
+   returns NULL. Uses CPLUS_DEMANGLE_V3, RUST_IS_MANGLED and
+   RUST_DEMANGLE_SYM.  Returns a new string that is owned by the caller.  */
+extern char *
+rust_demangle (const char *mangled, int options);
+
 enum gnu_v3_ctor_kinds {
   gnu_v3_complete_object_ctor = 1,
   gnu_v3_base_object_ctor,
@@ -451,7 +476,9 @@
   /* A transaction-safe function type.  */
   DEMANGLE_COMPONENT_TRANSACTION_SAFE,
   /* A cloned function.  */
-  DEMANGLE_COMPONENT_CLONE
+  DEMANGLE_COMPONENT_CLONE,
+  DEMANGLE_COMPONENT_NOEXCEPT,
+  DEMANGLE_COMPONENT_THROW_SPEC
 };
 
 /* Types which are only used internally.  */
@@ -469,6 +496,11 @@
   /* The type of this component.  */
   enum demangle_component_type type;
 
+  /* Guard against recursive component printing.
+     Initialize to zero.  Private to d_print_comp.
+     All other fields are final after initialization.  */
+  int d_printing;
+
   union
   {
     /* For DEMANGLE_COMPONENT_NAME.  */
@@ -663,7 +695,7 @@
 
 extern char *
 cplus_demangle_print (int options,
-                      const struct demangle_component *tree,
+                      struct demangle_component *tree,
                       int estimated_length,
                       size_t *p_allocated_size);
 
@@ -683,7 +715,7 @@
 
 extern int
 cplus_demangle_print_callback (int options,
-                               const struct demangle_component *tree,
+                               struct demangle_component *tree,
                                demangle_callbackref callback, void *opaque);
 
 #ifdef __cplusplus

Modified: trunk/coregrind/m_demangle/dyn-string.c
==============================================================================
--- trunk/coregrind/m_demangle/dyn-string.c (original)
+++ trunk/coregrind/m_demangle/dyn-string.c Wed Apr 12 14:01:29 2017
@@ -1,5 +1,5 @@
 /* An abstract string datatype.
-   Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
    Contributed by Mark Mitchell ([hidden email]).
 
 This file is part of GNU CC.

Modified: trunk/coregrind/m_demangle/dyn-string.h
==============================================================================
--- trunk/coregrind/m_demangle/dyn-string.h (original)
+++ trunk/coregrind/m_demangle/dyn-string.h Wed Apr 12 14:01:29 2017
@@ -1,5 +1,5 @@
 /* An abstract string datatype.
-   Copyright (C) 1998-2015 Free Software Foundation, Inc.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
    Contributed by Mark Mitchell ([hidden email]).
 
 This file is part of GCC.

Added: trunk/coregrind/m_demangle/rust-demangle.c
==============================================================================
--- trunk/coregrind/m_demangle/rust-demangle.c (added)
+++ trunk/coregrind/m_demangle/rust-demangle.c Wed Apr 12 14:01:29 2017
@@ -0,0 +1,363 @@
+/* Demangler for the Rust programming language
+   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+   Written by David Tolnay ([hidden email]).
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+In addition to the permissions in the GNU Library General Public
+License, the Free Software Foundation gives you unlimited permission
+to link the compiled version of this file into combinations with other
+programs, and to distribute those combinations without any restriction
+coming from the use of this file.  (The Library Public License
+restrictions do apply in other respects; for example, they cover
+modification of the file, and distribution when not linked into a
+combined executable.)
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB.
+If not, see <http://www.gnu.org/licenses/>.  */
+
+
+#if 0 /* in valgrind */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#include "safe-ctype.h"
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+extern size_t strlen(const char *s);
+extern int strncmp(const char *s1, const char *s2, size_t n);
+extern void *memset(void *s, int c, size_t n);
+#endif
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#include <demangle.h>
+#include "libiberty.h"
+#endif /* ! in valgrind */
+
+#include "vg_libciface.h"
+
+#include "ansidecl.h"
+#include "demangle.h"
+#include "safe-ctype.h"
+
+/* Mangled Rust symbols look like this:
+     _$LT$std..sys..fd..FileDesc$u20$as$u20$core..ops..Drop$GT$::drop::hc68340e1baa4987a
+
+   The original symbol is:
+     <std::sys::fd::FileDesc as core::ops::Drop>::drop
+
+   The last component of the path is a 64-bit hash in lowercase hex,
+   prefixed with "h". Rust does not have a global namespace between
+   crates, an illusion which Rust maintains by using the hash to
+   distinguish things that would otherwise have the same symbol.
+
+   Any path component not starting with a XID_Start character is
+   prefixed with "_".
+
+   The following escape sequences are used:
+
+   ","  =>  $C$
+   "@"  =>  $SP$
+   "*"  =>  $BP$
+   "&"  =>  $RF$
+   "<"  =>  $LT$
+   ">"  =>  $GT$
+   "("  =>  $LP$
+   ")"  =>  $RP$
+   " "  =>  $u20$
+   "\"" =>  $u22$
+   "'"  =>  $u27$
+   "+"  =>  $u2b$
+   ";"  =>  $u3b$
+   "["  =>  $u5b$
+   "]"  =>  $u5d$
+   "{"  =>  $u7b$
+   "}"  =>  $u7d$
+   "~"  =>  $u7e$
+
+   A double ".." means "::" and a single "." means "-".
+
+   The only characters allowed in the mangled symbol are a-zA-Z0-9 and _.:$  */
+
+static const char *hash_prefix = "::h";
+static const size_t hash_prefix_len = 3;
+static const size_t hash_len = 16;
+
+static int is_prefixed_hash (const char *start);
+static int looks_like_rust (const char *sym, size_t len);
+static int unescape (const char **in, char **out, const char *seq, char value);
+
+/* INPUT: sym: symbol that has been through C++ (gnu v3) demangling
+
+   This function looks for the following indicators:
+
+   1. The hash must consist of "h" followed by 16 lowercase hex digits.
+
+   2. As a sanity check, the hash must use between 5 and 15 of the 16
+      possible hex digits. This is true of 99.9998% of hashes so once
+      in your life you may see a false negative. The point is to
+      notice path components that could be Rust hashes but are
+      probably not, like "haaaaaaaaaaaaaaaa". In this case a false
+      positive (non-Rust symbol has an important path component
+      removed because it looks like a Rust hash) is worse than a false
+      negative (the rare Rust symbol is not demangled) so this sets
+      the balance in favor of false negatives.
+
+   3. There must be no characters other than a-zA-Z0-9 and _.:$
+
+   4. There must be no unrecognized $-sign sequences.
+
+   5. There must be no sequence of three or more dots in a row ("...").  */
+
+int
+rust_is_mangled (const char *sym)
+{
+  size_t len, len_without_hash;
+
+  if (!sym)
+    return 0;
+
+  len = strlen (sym);
+  if (len <= hash_prefix_len + hash_len)
+    /* Not long enough to contain "::h" + hash + something else */
+    return 0;
+
+  len_without_hash = len - (hash_prefix_len + hash_len);
+  if (!is_prefixed_hash (sym + len_without_hash))
+    return 0;
+
+  return looks_like_rust (sym, len_without_hash);
+}
+
+/* A hash is the prefix "::h" followed by 16 lowercase hex digits. The
+   hex digits must comprise between 5 and 15 (inclusive) distinct
+   digits.  */
+
+static int
+is_prefixed_hash (const char *str)
+{
+  const char *end;
+  char seen[16];
+  size_t i;
+  int count;
+
+  if (strncmp (str, hash_prefix, hash_prefix_len))
+    return 0;
+  str += hash_prefix_len;
+
+  memset (seen, 0, sizeof(seen));
+  for (end = str + hash_len; str < end; str++)
+    if (*str >= '0' && *str <= '9')
+      seen[*str - '0'] = 1;
+    else if (*str >= 'a' && *str <= 'f')
+      seen[*str - 'a' + 10] = 1;
+    else
+      return 0;
+
+  /* Count how many distinct digits seen */
+  count = 0;
+  for (i = 0; i < 16; i++)
+    if (seen[i])
+      count++;
+
+  return count >= 5 && count <= 15;
+}
+
+static int
+looks_like_rust (const char *str, size_t len)
+{
+  const char *end = str + len;
+
+  while (str < end)
+    switch (*str)
+      {
+      case '$':
+ if (!strncmp (str, "$C$", 3))
+  str += 3;
+ else if (!strncmp (str, "$SP$", 4)
+ || !strncmp (str, "$BP$", 4)
+ || !strncmp (str, "$RF$", 4)
+ || !strncmp (str, "$LT$", 4)
+ || !strncmp (str, "$GT$", 4)
+ || !strncmp (str, "$LP$", 4)
+ || !strncmp (str, "$RP$", 4))
+  str += 4;
+ else if (!strncmp (str, "$u20$", 5)
+ || !strncmp (str, "$u22$", 5)
+ || !strncmp (str, "$u27$", 5)
+ || !strncmp (str, "$u2b$", 5)
+ || !strncmp (str, "$u3b$", 5)
+ || !strncmp (str, "$u5b$", 5)
+ || !strncmp (str, "$u5d$", 5)
+ || !strncmp (str, "$u7b$", 5)
+ || !strncmp (str, "$u7d$", 5)
+ || !strncmp (str, "$u7e$", 5))
+  str += 5;
+ else
+  return 0;
+ break;
+      case '.':
+ /* Do not allow three or more consecutive dots */
+ if (!strncmp (str, "...", 3))
+  return 0;
+ /* Fall through */
+      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+      case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+      case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+      case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+      case 'y': case 'z':
+      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+      case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+      case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+      case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+      case 'Y': case 'Z':
+      case '0': case '1': case '2': case '3': case '4': case '5':
+      case '6': case '7': case '8': case '9':
+      case '_':
+      case ':':
+ str++;
+ break;
+      default:
+ return 0;
+      }
+
+  return 1;
+}
+
+/*
+  INPUT: sym: symbol for which rust_is_mangled(sym) returned 1.
+
+  The input is demangled in-place because the mangled name is always
+  longer than the demangled one.  */
+
+void
+rust_demangle_sym (char *sym)
+{
+  const char *in;
+  char *out;
+  const char *end;
+
+  if (!sym)
+    return;
+
+  in = sym;
+  out = sym;
+  end = sym + strlen (sym) - (hash_prefix_len + hash_len);
+
+  while (in < end)
+    switch (*in)
+      {
+      case '$':
+ if (!(unescape (&in, &out, "$C$", ',')
+      || unescape (&in, &out, "$SP$", '@')
+      || unescape (&in, &out, "$BP$", '*')
+      || unescape (&in, &out, "$RF$", '&')
+      || unescape (&in, &out, "$LT$", '<')
+      || unescape (&in, &out, "$GT$", '>')
+      || unescape (&in, &out, "$LP$", '(')
+      || unescape (&in, &out, "$RP$", ')')
+      || unescape (&in, &out, "$u20$", ' ')
+      || unescape (&in, &out, "$u22$", '\"')
+      || unescape (&in, &out, "$u27$", '\'')
+      || unescape (&in, &out, "$u2b$", '+')
+      || unescape (&in, &out, "$u3b$", ';')
+      || unescape (&in, &out, "$u5b$", '[')
+      || unescape (&in, &out, "$u5d$", ']')
+      || unescape (&in, &out, "$u7b$", '{')
+      || unescape (&in, &out, "$u7d$", '}')
+      || unescape (&in, &out, "$u7e$", '~'))) {
+  /* unexpected escape sequence, not looks_like_rust. */
+  goto fail;
+ }
+ break;
+      case '_':
+ /* If this is the start of a path component and the next
+   character is an escape sequence, ignore the underscore. The
+   mangler inserts an underscore to make sure the path
+   component begins with a XID_Start character. */
+ if ((in == sym || in[-1] == ':') && in[1] == '$')
+  in++;
+ else
+  *out++ = *in++;
+ break;
+      case '.':
+ if (in[1] == '.')
+  {
+    /* ".." becomes "::" */
+    *out++ = ':';
+    *out++ = ':';
+    in += 2;
+  }
+ else
+  {
+    /* "." becomes "-" */
+    *out++ = '-';
+    in++;
+  }
+ break;
+      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+      case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+      case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+      case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+      case 'y': case 'z':
+      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+      case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+      case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+      case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+      case 'Y': case 'Z':
+      case '0': case '1': case '2': case '3': case '4': case '5':
+      case '6': case '7': case '8': case '9':
+      case ':':
+ *out++ = *in++;
+ break;
+      default:
+ /* unexpected character in symbol, not looks_like_rust.  */
+ goto fail;
+      }
+  goto done;
+
+fail:
+  *out++ = '?'; /* This is pretty lame, but it's hard to do better. */
+done:
+  *out = '\0';
+}
+
+static int
+unescape (const char **in, char **out, const char *seq, char value)
+{
+  size_t len = strlen (seq);
+
+  if (strncmp (*in, seq, len))
+    return 0;
+
+  **out = value;
+
+  *in += len;
+  *out += 1;
+
+  return 1;
+}

Modified: trunk/coregrind/m_demangle/safe-ctype.c
==============================================================================
--- trunk/coregrind/m_demangle/safe-ctype.c (original)
+++ trunk/coregrind/m_demangle/safe-ctype.c Wed Apr 12 14:01:29 2017
@@ -1,7 +1,6 @@
 /* <ctype.h> replacement macros.
 
-   Copyright (C) 2000, 2001, 2002, 2003, 2004,
-   2005 Free Software Foundation, Inc.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
    Contributed by Zack Weinberg <[hidden email]>.
 
 This file is part of the libiberty library.

Modified: trunk/coregrind/m_demangle/safe-ctype.h
==============================================================================
--- trunk/coregrind/m_demangle/safe-ctype.h (original)
+++ trunk/coregrind/m_demangle/safe-ctype.h Wed Apr 12 14:01:29 2017
@@ -1,6 +1,6 @@
 /* <ctype.h> replacement macros.
 
-   Copyright (C) 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
    Contributed by Zack Weinberg <[hidden email]>.
 
 This file is part of the libiberty library.


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Valgrind-developers mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers
Loading...