/* Demangler for g++ V3 ABI.
- Copyright (C) 2003-2019 Free Software Foundation, Inc.
+ Copyright (C) 2003-2020 Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@wasabisystems.com>.
This file is part of the libiberty library, which is part of GCC.
#else
#ifdef __STDC__
#ifdef __STDC_VERSION__
-#if __STDC_VERSION__ >= 199901L
+#if __STDC_VERSION__ >= 199901L && !__STDC_NO_VLA__
#define CP_DYNAMIC_ARRAYS
-#endif /* __STDC__VERSION >= 199901L */
+#endif /* __STDC_VERSION__ >= 199901L && !__STDC_NO_VLA__ */
#endif /* defined (__STDC_VERSION__) */
#endif /* defined (__STDC__) */
#endif /* ! defined (__GNUC__) */
static void
d_print_init (struct d_print_info *, demangle_callbackref, void *,
- const struct demangle_component *);
+ struct demangle_component *);
static inline void d_print_error (struct d_print_info *);
int
cplus_demangle_fill_name (struct demangle_component *p, const char *s, int len)
{
- if (p == NULL || s == NULL || len == 0)
+ if (p == NULL || s == NULL || len <= 0)
return 0;
p->d_printing = 0;
+ p->d_counting = 0;
p->type = DEMANGLE_COMPONENT_NAME;
p->u.s_name.s = s;
p->u.s_name.len = len;
if (p == NULL || args < 0 || name == NULL)
return 0;
p->d_printing = 0;
+ p->d_counting = 0;
p->type = DEMANGLE_COMPONENT_EXTENDED_OPERATOR;
p->u.s_extended_operator.args = args;
p->u.s_extended_operator.name = name;
|| (int) kind > gnu_v3_object_ctor_group)
return 0;
p->d_printing = 0;
+ p->d_counting = 0;
p->type = DEMANGLE_COMPONENT_CTOR;
p->u.s_ctor.kind = kind;
p->u.s_ctor.name = name;
|| (int) kind > gnu_v3_object_dtor_group)
return 0;
p->d_printing = 0;
+ p->d_counting = 0;
p->type = DEMANGLE_COMPONENT_DTOR;
p->u.s_dtor.kind = kind;
p->u.s_dtor.name = name;
return NULL;
p = &di->comps[di->next_comp];
p->d_printing = 0;
+ p->d_counting = 0;
++di->next_comp;
return p;
}
really apply here; this happens when parsing a class
which is local to a function. */
if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME)
- while (is_fnqual_component_type (d_right (dc)->type))
- d_right (dc) = d_left (d_right (dc));
+ {
+ while (d_right (dc) != NULL
+ && is_fnqual_component_type (d_right (dc)->type))
+ d_right (dc) = d_left (d_right (dc));
+
+ if (d_right (dc) == NULL)
+ dc = NULL;
+ }
}
else
{
}
if (ret > ((INT_MAX - (peek - '0')) / 10))
return -1;
- ret = ret * 10 + peek - '0';
+ ret = ret * 10 + (peek - '0');
d_advance (di, 1);
peek = d_peek_char (di);
}
{ "ad", NL ("&"), 1 },
{ "an", NL ("&"), 2 },
{ "at", NL ("alignof "), 1 },
+ { "aw", NL ("co_await "), 1 },
{ "az", NL ("alignof "), 1 },
{ "cc", NL ("const_cast"), 2 },
{ "cl", NL ("()"), 2 },
{ "sP", NL ("sizeof..."), 1 },
{ "sZ", NL ("sizeof..."), 1 },
{ "sc", NL ("static_cast"), 2 },
+ { "ss", NL ("<=>"), 2 },
{ "st", NL ("sizeof "), 1 },
{ "sz", NL ("sizeof "), 1 },
{ "tr", NL ("throw"), 0 },
d_advance (di, 2);
if (peek == 't')
type = cplus_demangle_type (di);
- if (!d_peek_next_char (di))
+ if (!d_peek_char (di) || !d_peek_next_char (di))
return NULL;
return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST,
type, d_exprlist (di, 'E'));
&& type->u.s_builtin.type->print != D_PRINT_DEFAULT)
di->expansion -= type->u.s_builtin.type->len;
+ if (type->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
+ && strcmp (type->u.s_builtin.type->name,
+ cplus_demangle_builtin_types[33].name) == 0)
+ {
+ if (d_peek_char (di) == 'E')
+ {
+ d_advance (di, 1);
+ return type;
+ }
+ }
+
/* Rather than try to interpret the literal value, we just
collect it as a string. Note that it's possible to have a
floating point literal here. The ABI specifies that the
are larger than the actual numbers encountered. */
static void
-d_count_templates_scopes (int *num_templates, int *num_scopes,
- const struct demangle_component *dc)
+d_count_templates_scopes (struct d_print_info *dpi,
+ struct demangle_component *dc)
{
- if (dc == NULL)
+ if (dc == NULL || dc->d_counting > 1 || dpi->recursion > MAX_RECURSION_COUNT)
return;
+ ++ dc->d_counting;
+
switch (dc->type)
{
case DEMANGLE_COMPONENT_NAME:
break;
case DEMANGLE_COMPONENT_TEMPLATE:
- (*num_templates)++;
+ dpi->num_copy_templates++;
goto recurse_left_right;
case DEMANGLE_COMPONENT_REFERENCE:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
if (d_left (dc)->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
- (*num_scopes)++;
+ dpi->num_saved_scopes++;
goto recurse_left_right;
case DEMANGLE_COMPONENT_QUAL_NAME:
case DEMANGLE_COMPONENT_TAGGED_NAME:
case DEMANGLE_COMPONENT_CLONE:
recurse_left_right:
- d_count_templates_scopes (num_templates, num_scopes,
- d_left (dc));
- d_count_templates_scopes (num_templates, num_scopes,
- d_right (dc));
+ /* PR 89394 - Check for too much recursion. */
+ if (dpi->recursion > DEMANGLE_RECURSION_LIMIT)
+ /* FIXME: There ought to be a way to report to the
+ user that the recursion limit has been reached. */
+ return;
+
+ ++ dpi->recursion;
+ d_count_templates_scopes (dpi, d_left (dc));
+ d_count_templates_scopes (dpi, d_right (dc));
+ -- dpi->recursion;
break;
case DEMANGLE_COMPONENT_CTOR:
- d_count_templates_scopes (num_templates, num_scopes,
- dc->u.s_ctor.name);
+ d_count_templates_scopes (dpi, dc->u.s_ctor.name);
break;
case DEMANGLE_COMPONENT_DTOR:
- d_count_templates_scopes (num_templates, num_scopes,
- dc->u.s_dtor.name);
+ d_count_templates_scopes (dpi, dc->u.s_dtor.name);
break;
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
- d_count_templates_scopes (num_templates, num_scopes,
- dc->u.s_extended_operator.name);
+ d_count_templates_scopes (dpi, dc->u.s_extended_operator.name);
break;
case DEMANGLE_COMPONENT_FIXED_TYPE:
- d_count_templates_scopes (num_templates, num_scopes,
- dc->u.s_fixed.length);
+ d_count_templates_scopes (dpi, dc->u.s_fixed.length);
break;
case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
- d_count_templates_scopes (num_templates, num_scopes,
- d_left (dc));
+ d_count_templates_scopes (dpi, d_left (dc));
break;
case DEMANGLE_COMPONENT_LAMBDA:
case DEMANGLE_COMPONENT_DEFAULT_ARG:
- d_count_templates_scopes (num_templates, num_scopes,
- dc->u.s_unary_num.sub);
+ d_count_templates_scopes (dpi, dc->u.s_unary_num.sub);
break;
}
}
static void
d_print_init (struct d_print_info *dpi, demangle_callbackref callback,
- void *opaque, const struct demangle_component *dc)
+ void *opaque, struct demangle_component *dc)
{
dpi->len = 0;
dpi->last_char = '\0';
dpi->next_copy_template = 0;
dpi->num_copy_templates = 0;
- d_count_templates_scopes (&dpi->num_copy_templates,
- &dpi->num_saved_scopes, dc);
+ d_count_templates_scopes (dpi, dc);
+ /* If we did not reach the recursion limit, then reset the
+ current recursion value back to 0, so that we can print
+ the templates. */
+ if (dpi->recursion < DEMANGLE_RECURSION_LIMIT)
+ dpi->recursion = 0;
dpi->num_copy_templates *= dpi->num_saved_scopes;
dpi->current_template = NULL;
typed_name = d_right (typed_name);
if (typed_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
typed_name = typed_name->u.s_unary_num.sub;
- if (typed_name == NULL)
- {
- d_print_error (dpi);
- return;
- }
- while (is_fnqual_component_type (typed_name->type))
+ while (typed_name != NULL
+ && is_fnqual_component_type (typed_name->type))
{
if (i >= sizeof adpm / sizeof adpm[0])
{
typed_name = d_left (typed_name);
}
+ if (typed_name == NULL)
+ {
+ d_print_error (dpi);
+ return;
+ }
}
/* If typed_name is a template, then it applies to the
d_append_string (dpi, "&&");
return;
case DEMANGLE_COMPONENT_COMPLEX:
- d_append_string (dpi, "complex ");
+ d_append_string (dpi, " _Complex");
return;
case DEMANGLE_COMPONENT_IMAGINARY:
- d_append_string (dpi, "imaginary ");
+ d_append_string (dpi, " _Imaginary");
return;
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
if (d_last_char (dpi) != '(')