This patch almost a decade ago:
...
2007-08-31 Douglas Gregor <doug.gregor@gmail.com>
* cp-demangle.c (d_dump): Handle
DEMANGLE_COMPONENT_RVALUE_REFERENCE.
(d_make_comp): Ditto.
...
... missed doing the same change to cplus_demangle_fill_component that
was done to d_make_comp. I.e., teach it to only validate that we're
not passing in a "right" subtree. GDB has recently (finally) learned
about rvalue references, and a change to make it use
cplus_demangle_fill_component more ran into an assertion because of
this.
(GDB is the only user of cplus_demangle_fill_component in both the gcc
and binutils-gdb trees.)
libiberty/ChangeLog:
2017-03-27 Pedro Alves <palves@redhat.com>
* cp-demint.c (cplus_demangle_fill_component): Handle
DEMANGLE_COMPONENT_RVALUE_REFERENCE.
From-SVN: r246502
The fix for bug 59195:
[C++ demangler handles conversion operator incorrectly]
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59195
unfortunately makes the demangler crash due to infinite recursion, in
case of casts in template parameters.
For example, with:
template<int> struct A {};
template <typename Y> void function_temp(A<sizeof ((Y)(999))>) {}
template void function_temp<int>(A<sizeof (int)>);
The 'function_temp<int>' instantiation above mangles to:
_Z13function_tempIiEv1AIXszcvT_Li999EEE
The demangler parses this as:
typed name
template
name 'function_temp'
template argument list
builtin type int
function type
builtin type void
argument list
template (*)
name 'A'
template argument list
unary operator
operator sizeof
unary operator
cast
template parameter 0 (**)
literal
builtin type int
name '999'
And after the fix for 59195, due to:
static void
d_print_cast (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
...
/* For a cast operator, we need the template parameters from
the enclosing template in scope for processing the type. */
if (dpi->current_template != NULL)
{
dpt.next = dpi->templates;
dpi->templates = &dpt;
dpt.template_decl = dpi->current_template;
}
when printing the template argument list of A (what should be "<sizeof
(int)>"), the template parameter 0 (that is, "T_", the '**' above) now
refers to the first parameter of the the template argument list of the
'A' template (the '*' above), exactly what we were already trying to
print. This leads to infinite recursion, and stack exaustion. The
template parameter 0 should actually refer to the first parameter of
the 'function_temp' template.
Where it reads "for the cast operator" in the comment in d_print_cast
(above), it's really talking about a conversion operator, like:
struct A { template <typename U> explicit operator U(); };
We don't want to inject the template parameters from the enclosing
template in scope when processing a cast _expression_, only when
handling a conversion operator.
The problem is that DEMANGLE_COMPONENT_CAST is currently ambiguous,
and means _both_ 'conversion operator' and 'cast expression'.
Fix this by adding a new DEMANGLE_COMPONENT_CONVERSION component type,
which does what DEMANGLE_COMPONENT_CAST does today, and making
DEMANGLE_COMPONENT_CAST just simply print its component subtree.
I think we could instead reuse DEMANGLE_COMPONENT_CAST and in
d_print_comp_inner still do:
@@ -5001,9 +5013,9 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
d_print_comp (dpi, options, dc->u.s_extended_operator.name);
return;
case DEMANGLE_COMPONENT_CAST:
d_append_string (dpi, "operator ");
- d_print_cast (dpi, options, dc);
+ d_print_conversion (dpi, options, dc);
return;
leaving the unary cast case below calling d_print_cast, but seems to
me that spliting the component types makes it easier to reason about
the code.
g++'s testsuite actually generates three symbols that crash the
demangler in the same way. I've added those as tests in the demangler
testsuite as well.
And then this fixes PR other/61233 too, which happens to be a
demangler crash originally reported to GDB, at:
https://sourceware.org/bugzilla/show_bug.cgi?id=16957
Bootstrapped and regtested on x86_64 Fedora 20.
Also ran this through GDB's testsuite. GDB will require a small
update to use DEMANGLE_COMPONENT_CONVERSION in one place it's using
DEMANGLE_COMPONENT_CAST in its sources.
libiberty/
2015-11-27 Pedro Alves <palves@redhat.com>
PR other/61321
PR other/61233
* demangle.h (enum demangle_component_type)
<DEMANGLE_COMPONENT_CONVERSION>: New value.
* cp-demangle.c (d_demangle_callback, d_make_comp): Handle
DEMANGLE_COMPONENT_CONVERSION.
(is_ctor_dtor_or_conversion): Handle DEMANGLE_COMPONENT_CONVERSION
instead of DEMANGLE_COMPONENT_CAST.
(d_operator_name): Return a DEMANGLE_COMPONENT_CONVERSION
component if handling a conversion.
(d_count_templates_scopes, d_print_comp_inner): Handle
DEMANGLE_COMPONENT_CONVERSION.
(d_print_comp_inner): Handle DEMANGLE_COMPONENT_CONVERSION instead
of DEMANGLE_COMPONENT_CAST.
(d_print_cast): Rename as ...
(d_print_conversion): ... this. Adjust comments.
(d_print_cast): Rewrite - simply print the left subcomponent.
* cp-demint.c (cplus_demangle_fill_component): Handle
DEMANGLE_COMPONENT_CONVERSION.
* testsuite/demangle-expected: Add tests.
From-SVN: r231020
Change "if (E) free (E);" to "free (E);" everywhere except in the
libgo/, intl/, zlib/ and classpath/ directories.
Also transform equivalent variants like
"if (E != NULL) free (E);" and allow an extra cast on the
argument to free. Otherwise, the tested and freed "E"
expressions must be identical, modulo white space.
From-SVN: r172785
include/
2005-05-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
* libiberty.h (ACONCAT): Properly cast value of alloca().
* ansidecl.h (ATTRIBUTE_UNUSED_LABEL): Don't define if
__cplusplus.
libiberty/
2005-05-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
* configure.ac: Check declarations for calloc(), getenv(),
malloc(), realloc() and sbrk().
* config.in: Regenerate.
* configure: Likewise.
* alloca.c (C_alloca): Change "new" to "new_storage". Use XNEWVEC
instead of xmalloc.
* choose-temp.c (choose_temp_base): Use XNEWVEC instea od xmalloc.
* concat.c (liiberty_concat_ptr): Surround definition with an
extern "C" block, if __cplusplus.
(concat): Use XNEWVEC instead of xmalloc.
(reconcat): Likewise.
* cp-demangle.c (struct d_print_template): Rename member
"template" to "template_decl". Adjust use throughout the file.
(d_print_resize): Properly cast return value of realloc().
(cplus_demangle_print): Same for malloc().
(d_demangle): Likewise.
* cp-demint.c (cplus_demangle_fill_builtin_type): Rename parameter
"typename" to "type_name".
* cplus-dem.c (grow_vect): Use XRESIZEVEC instead of xrealloc().
(work_stuff_copy_to_from): Use XNEWVEC insteand of xmalloc().
(demangle_template_value_parm): Likewise.
(demangle_template): Likewise.
(recursively_demangle): Likewise.
(do_hpacc_template_literal): Likewise.
(do_arg): Likewise.
(remember_type): Likewise.
(remember_Ktype): Likewise.
(register_Btype): Likewise.
(string_need): Use XRESIZEVEC instead of xrealloc().
* dyn-string.c (dyn_string_init): Use XNEWVEC.
(dyn_string_new): Use XNEW.
(dyn_string_resize): Use XRESIZEVEC.
* fnmatch.c (fnmatch): Rename local variable "not" to "negate".
* getopt.c (getenv): Declare only if !__cplusplus and !getenv.
Otherwise include <stdlib.h>.
(exchange): Cast return value of malloc().
* hashtab.c (htab_size): Define as both macro and non-inline
function.
(htab_elements): Likewise.
* getpwd.c (getpwd): Use XNEWVEC.
(htab_create_alloc_ex): Use C90 prototype-style.
* lrealpath.c (lrealpath): Appropriately cast return value of
malloc().
* make-relative-prefix.c (save_string): Likewise.
* make-temp-file.c (try_dir): Rename from "try". Adjust use in
the file.
(choose_tmpdir): Use XNEWVEC.
* mkstemps.c (mkstemps): Rename parameter "template" to "pattern".
* pex-common.c (pex_init_common): Use XNEW.
(pex_add_remove): Use XRESIZEVEC.
(pex_run): Likewise.
(pex_get_status_and_time): Likewise.
* pex-djgpp.c (pex_djgpp_exec_child): Likewise.
* pex-msdos.c (pex_init): Use XNEW.
(pex_msdos_exec_child): Likewise.
(pex_msdos_exec_child): Use XRESIZEVEC.
* pex-unix.c (pex_wait): Use XNEW.
* pex-win32.c (fix_argv): Use XNEWVEC.
* pexecute.c (pwait): Likewise.
* setenv.c (setenv): Properly cast return value of malloc().
* sigsetmask.c (sigsetmask): Rename local variables "old" and
"new" to "old_sig" and "new_sig".
* sort.c (main): Use XNEWVEC.
* spaces.c (spaces): Cast return value of malloc().
* strndup.c (strndup): Likewise.
* ternary.c (ternary_insert): Use XNEW.
* xmalloc.c (malloc, realloc, calloc, sbrk): Surround declaration
with an extern "C" block if __cplusplus.
* xstrdup.c (xstrdup): Cast return value of memcpy().
* xstrerror.c (strerror): Enclose declaration in an extern "C"
block if __cplusplus.
* xstrndup.c (xstrndup): Use XNEW. Cast return value of memcpy().
From-SVN: r100115
* demangle.h (enum demangle_component_type): Define.
(struct demangle_operator_info): Declare.
(struct demangle_builtin_type_info): Declare.
(struct demangle_component): Define.
(cplus_demangle_fill_component): Declare.
(cplus_demangle_fill_name): Declare.
(cplus_demangle_fill_builtin_type): Declare.
(cplus_demangle_fill_operator): Declare.
(cplus_demangle_fill_extended_operator): Declare.
(cplus_demangle_fill_ctor, cplus_demangle_fill_dtor): Declare.
(cplus_demangle_v3_components): Declare.
(cplus_demangle_print): Declare.
* cp-demangle.c: Include "cp-demangle.h". If IN_GLIBCPP_V3 is
defined, rename some functions which are to become static via
#define.
(CP_STATIC_IF_GLIBCPP_V3): Define.
(struct d_operator_info): Move definition to cp-demangle.h, and
rename to demangle_operator_info. Change all uses.
(enum d_builtin_type_print): Move definition to cp-demangle.h.
(struct d_builtin_type_info): Move definition to cp-demangle.h,
and rename to demangle_builtin_type_info. Change all uses.
(enum d_comp_type): Move definition to include/demangle.h, and
rename to demangle_component_type, and change all enums to start
with DEMANGLE_COMPONENT_ instead of D_. Change all uses.
(struct d_comp): Move definition to include/demangle.h, and rename
to demangle_component. Change all uses.
(struct d_info): Move definition to cp-demangle.h.
(cplus_demangle_fill_name): New function.
(cplus_demangle_fill_extended_operator): New function.
(cplus_demangle_fill_ctor): New function.
(cplus_demangle_fill_dtor): New function.
(d_make_empty): Remove type parameter. Change all callers.
(d_make_name): Use cplus_demangle_fill_name.
(d_make_extended_operator): Use
cplus_demangle_fill_extended_operator.
(d_make_ctor): Use cplus_demangle_fill_ctor.
(d_make_dtor): Use cplus_demangle_fill_dtor.
(cplus_demangle_mangled_name): Rename from d_mangled_name. Make
non-static by default. Change all callers.
(cplus_demangle_operators): Rename from d_operators. Change all
uses. Make non-static by default. Add sentinel at end of array.
(d_operator_name): Adjust initialization of high for new sentinel
in cplus_demangle_operators.
(cplus_demangle_builtin_types): Rename from d_builtin_types.
Change all uses. Make non-static by default. Change initializer
to use D_BUILTIN_TYPE_COUNT instead of magic number 26.
(cplus_demangle_type): Rename from d_type. Make non-static by
default. Change all callers.
(cplus_demangle_init_info): Rename from d_init_info. Make
non-static by default. Change all callers.
* cp-demangle.h: New file.
* cp-demint.c: New file.
* Makefile.in: Rebuild dependencies.
(CFILES): Add cp-demint.c.
(REQUIRED_OFILES): Add cp-demint.o.
From-SVN: r75748