Discussion:
Valgrind: r16302 - in /trunk: ./ auxprogs/ coregrind/ coregrind/m_demangle/
(too old to reply)
s***@valgrind.org
2017-04-12 13:01:30 UTC
Permalink
Raw Message
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 <***@wasabisystems.com>.

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 <***@wasabisystems.com>.

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 (***@jclark.uucp)
Rewritten by Fred Fish (***@cygnus.com) for ARM and Lucid demangling
Modified by Satish Pai (***@apollo.hp.com) 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 (***@gdcproject.org)

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 (***@markmitchell.com).

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 (***@markmitchell.com).

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 (***@gmail.com).
+
+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 <***@stanford.edu>.

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 <***@stanford.edu>.

This file is part of the libiberty library.

Loading...