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
libiberty/
* cp-demangle.c (d_dump): Fix syntax error.
(d_identifier): Adjust type of len to match d_source_name.
(d_expression_1): Fix out-of-bounds access. Check code variable for
NULL before dereferencing it.
(d_find_pack): Do not recurse for FIXED_TYPE, DEFAULT_ARG and NUMBER.
(d_print_comp_inner): Add NULL pointer check.
* cp-demangle.h (d_peek_next_char): Define as inline function when
CHECK_DEMANGLER is defined.
(d_advance): Likewise.
* testsuite/demangle-expected: Add new testcases.
From-SVN: r225727
PR c++/44282
gcc/cp/
* mangle.c (attr_strcmp): New.
(write_CV_qualifiers_for_type): Also write out attributes that
affect type identity.
(write_type): Strip all attributes after writing qualifiers.
libiberty/
* cp-demangle.c (cplus_demangle_type): Handle arguments to vendor
extended qualifier.
From-SVN: r224007
* cp-demangle.c (d_dump): Only access field from s_fixed part of
the union for DEMANGLE_COMPONENT_FIXED_TYPE.
(d_count_templates_scopes): Likewise.
From-SVN: r214740
Running the demangler's testsuite with CP_DEMANGLE_DEBUG defined
crashes, with:
Program received signal SIGSEGV, Segmentation fault.
0x000000000040a8c3 in d_dump (dc=0x1, indent=12) at ../../src/libiberty/cp-demangle.c:567
567 switch (dc->type)
(gdb) bt 3
#0 0x000000000040a8c3 in d_dump (dc=0x1, indent=12) at ../../src/libiberty/cp-demangle.c:567
#1 0x000000000040ae47 in d_dump (dc=0x7fffffffd098, indent=10) at ../../src/libiberty/cp-demangle.c:787
#2 0x000000000040ae47 in d_dump (dc=0x7fffffffd0c8, indent=8) at ../../src/libiberty/cp-demangle.c:787
Note dc=0x1, which is obviously a bogus pointer. This is the end of
d_dump recursing for a component type that that doesn't actually have
subtrees:
787 d_dump (d_left (dc), indent + 2);
788 d_dump (d_right (dc), indent + 2);
This fixes the two cases the testsuite currently trips on.
libiberty/
2014-05-28 Pedro Alves <palves@redhat.com>
* cp-demangle.c (d_dump): Handle DEMANGLE_COMPONENT_FUNCTION_PARAM
and DEMANGLE_COMPONENT_NUMBER.
From-SVN: r211035
libiberty/
2014-05-08 Gary Benson <gbenson@redhat.com>
* cp-demangle.c (struct d_component_stack): New structure.
(struct d_print_info): New field component_stack.
(d_print_init): Initialize the above.
(d_print_comp_inner): Renamed from d_print_comp.
Do not restore template stack if it would cause a loop.
(d_print_comp): New function.
* testsuite/demangle-expected: New test cases.
From-SVN: r210205
libiberty/
2014-01-06 Gary Benson <gbenson@redhat.com>
* cp-demangle.c (struct d_print_info): New fields
next_saved_scope, copy_templates, next_copy_template and
num_copy_templates.
(d_count_templates): New function.
(d_print_init): New parameter "dc".
Estimate numbers of templates and scopes required.
(d_print_free): Removed function.
(cplus_demangle_print_callback): Allocate stack for
templates and scopes. Removed call to d_print_free.
(d_copy_templates): Removed function.
(d_save_scope): New function.
(d_get_saved_scope): Likewise.
(d_print_comp): Replace state saving/restoring code with
calls to d_save_scope and d_get_saved_scope.
From-SVN: r206362
libiberty/
PR other/59195
* cp-demangle.c (struct d_info_checkpoint): New struct.
(struct d_print_info): Add current_template field.
(d_operator_name): Set flag when processing a conversion
operator.
(cplus_demangle_type): When processing <template-args> for
a conversion operator, backtrack if necessary.
(d_expression_1): Renamed from d_expression.
(d_expression): New wrapper around d_expression_1.
(d_checkpoint): New function.
(d_backtrack): New function.
(d_print_init): Initialize current_template.
(d_print_comp): Set current_template.
(d_print_cast): Put current_template in scope for
printing conversion operator name.
(cplus_demangle_init_info): Initialize is_expression and
is_conversion.
* cp-demangle.h (struct d_info): Add is_expression and
is_conversion fields.
* testsuite/demangle-expected: New test cases.
From-SVN: r205292
* cp-demangle.c (d_copy_templates): Cast result of malloc
to (struct d_print_template *).
(d_print_comp): Cast result of realloc to (struct d_saved scope *).
From-SVN: r204713
libiberty/
2013-10-25 Gary Benson <gbenson@redhat.com>
* cp-demangle.c (struct d_saved_scope): New structure.
(struct d_print_info): New fields saved_scopes and
num_saved_scopes.
(d_print_init): Initialize the above.
(d_print_free): New function.
(cplus_demangle_print_callback): Call the above.
(d_copy_templates): New function.
(d_print_comp): New variables saved_templates and
need_template_restore.
[DEMANGLE_COMPONENT_REFERENCE,
DEMANGLE_COMPONENT_RVALUE_REFERENCE]: Capture scope the first
time the component is traversed, and use the captured scope for
subsequent traversals.
* testsuite/demangle-expected: Add regression test.
From-SVN: r204068
2013-09-10 Paolo Carlini <paolo.carlini@oracle.com>
PR bootstrap/58386
Revert:
2013-09-10 Gary Benson <gbenson@redhat.com>
* cp-demangle.c: Include hashtab.h.
(struct d_print_info): New field saved_scopes.
(d_print_init): Initialize the above.
(d_print_free): New function.
(cplus_demangle_print_callback): Call the above.
(struct d_saved_scope): New structure.
(d_store_scope): New function.
(d_free_scope) Likewise.
(d_restore_scope) Likewise.
(d_hash_saved_scope) Likewise.
(d_equal_saved_scope) Likewise.
(d_print_comp): New variable saved_scope.
[DEMANGLE_COMPONENT_REFERENCE,
DEMANGLE_COMPONENT_RVALUE_REFERENCE]: Capture scope the first
time the component is traversed, and use the captured scope for
subsequent traversals.
From-SVN: r202480
2013-09-10 Gary Benson <gbenson@redhat.com>
* cp-demangle.c: Include hashtab.h.
(struct d_print_info): New field saved_scopes.
(d_print_init): Initialize the above.
(d_print_free): New function.
(cplus_demangle_print_callback): Call the above.
(struct d_saved_scope): New structure.
(d_store_scope): New function.
(d_free_scope) Likewise.
(d_restore_scope) Likewise.
(d_hash_saved_scope) Likewise.
(d_equal_saved_scope) Likewise.
(d_print_comp): New variable saved_scope.
[DEMANGLE_COMPONENT_REFERENCE,
DEMANGLE_COMPONENT_RVALUE_REFERENCE]: Capture scope the first
time the component is traversed, and use the captured scope for
subsequent traversals.
From-SVN: r202442
libiberty/
* cp-demangle.c (cplus_demangle_type): Fix function quals.
(d_pointer_to_member_type): Simplify.
gcc/cp/
* mangle.c (write_type): When writing a function type with
function-cv-quals, don't add the unqualified type as a
substitution candidate.
From-SVN: r197460
PR c++/48665
* cp-demangle.c (d_cv_qualifiers): If qualifiers are applied to a
function type, change them to apply to the "this" parameter.
* testsuite/demangle-expected: Add test case.
From-SVN: r179772
include/ChangeLog:
PR 40831
* demangle.h (enum demangle_component_type): Add
DEMANGLE_COMPONENT_CLONE.
libiberty/ChangeLog:
PR 40831
* cp-demangle.c (d_make_comp): Add new component type.
(cplus_demangle_mangled_name): Check for clone suffixes.
(d_parmlist): Don't error out if we see '.'.
(d_clone_suffix): New function.
(d_print_comp): Print info for clone suffixes.
* testsuite/demangle-expected: Add new testcases.
From-SVN: r179132
libiberty/
PR debug/49408
* cp-demangle.c (d_print_comp): Suppress argument list for function
references by the '&' unary operator. Keep also already processed
variant without the argument list. Suppress argument list types for
function call used in an expression.
* testsuite/demangle-expected: Fix excessive argument list types in
`test for typed function in decltype'. New testcase for no argument
list types printed. 3 new testcases for function references by the
'&' unary operator..
From-SVN: r175761
include/
* demangle.h (DMGL_RET_POSTFIX): Extend the comment.
(DMGL_RET_DROP): New.
libiberty/
* cp-demangle.c (d_print_comp) <DEMANGLE_COMPONENT_FUNCTION_TYPE>: Do
not pass DMGL_RET_POSTFIX or DMGL_RET_DROP. Support DMGL_RET_DROP.
* testsuite/demangle-expected: New testcases for --ret-drop.
* testsuite/test-demangle.c: Document --ret-drop in a comment.
(main): New variable ret_drop, fill it, call cplus_demangle with it.
From-SVN: r175000
libiberty/:
PR other/46332
* cp-demangle.c (d_print_function_type): Don't print parentheses
if there are no modifiers to print.
* testsuite/demangle-expected: Tweak one test case, add another.
libstdc++/:
* testsuite/abi/demangle/abi_examples/14.cc (main): Change
expected demangling.
From-SVN: r166695
PR other/43838
* cp-demangle.c (struct d_print_info): Add flush_count field.
(d_print_init): Initialize it to 0.
(d_print_flush): Increment it.
(d_print_comp): If needed flush before appending ", ". Only
decrement dpi->len if no flushes happened during the recursive
call.
* testsuite/demangle-expected: Add a test for this.
From-SVN: r160554
* c-pretty-print.c (pp_c_specifier_qualifier_list) [VECTOR_TYPE]:
Use () rather than [], and move before the element type.
* cp-demangle.c (d_print_mod): Use () rather than [] for vectors.
From-SVN: r157650