diff options
Diffstat (limited to 'libiberty/cp-demangle.c')
-rw-r--r-- | libiberty/cp-demangle.c | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 3d5d33ef591..68d8ee16c93 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -275,6 +275,16 @@ struct d_growable_string int allocation_failure; }; +/* Stack of components, innermost first, used to avoid loops. */ + +struct d_component_stack +{ + /* This component. */ + const struct demangle_component *dc; + /* This component's parent. */ + const struct d_component_stack *parent; +}; + /* A demangle component and some scope captured when it was first traversed. */ @@ -327,6 +337,8 @@ struct d_print_info int pack_index; /* Number of d_print_flush calls so far. */ unsigned long int flush_count; + /* Stack of components, innermost first, used to avoid loops. */ + const struct d_component_stack *component_stack; /* Array of saved scopes for evaluating substitutions. */ struct d_saved_scope *saved_scopes; /* Index of the next unused saved scope in the above array. */ @@ -3934,6 +3946,8 @@ d_print_init (struct d_print_info *dpi, demangle_callbackref callback, dpi->demangle_failure = 0; + dpi->component_stack = NULL; + dpi->saved_scopes = NULL; dpi->next_saved_scope = 0; dpi->num_saved_scopes = 0; @@ -4269,8 +4283,8 @@ d_get_saved_scope (struct d_print_info *dpi, /* Subroutine to handle components. */ static void -d_print_comp (struct d_print_info *dpi, int options, - const struct demangle_component *dc) +d_print_comp_inner (struct d_print_info *dpi, int options, + const struct demangle_component *dc) { /* Magic variable to let reference smashing skip over the next modifier without needing to modify *dc. */ @@ -4673,11 +4687,30 @@ d_print_comp (struct d_print_info *dpi, int options, } else { + const struct d_component_stack *dcse; + int found_self_or_parent = 0; + /* This traversal is reentering SUB as a substition. - Restore the original templates temporarily. */ - saved_templates = dpi->templates; - dpi->templates = scope->templates; - need_template_restore = 1; + If we are not beneath SUB or DC in the tree then we + need to restore SUB's template stack temporarily. */ + for (dcse = dpi->component_stack; dcse != NULL; + dcse = dcse->parent) + { + if (dcse->dc == sub + || (dcse->dc == dc + && dcse != dpi->component_stack)) + { + found_self_or_parent = 1; + break; + } + } + + if (!found_self_or_parent) + { + saved_templates = dpi->templates; + dpi->templates = scope->templates; + need_template_restore = 1; + } } a = d_lookup_template_argument (dpi, sub); @@ -5316,6 +5349,21 @@ d_print_comp (struct d_print_info *dpi, int options, } } +static void +d_print_comp (struct d_print_info *dpi, int options, + const struct demangle_component *dc) +{ + struct d_component_stack self; + + self.dc = dc; + self.parent = dpi->component_stack; + dpi->component_stack = &self; + + d_print_comp_inner (dpi, options, dc); + + dpi->component_stack = self.parent; +} + /* Print a Java dentifier. For Java we try to handle encoded extended Unicode characters. The C++ ABI doesn't mention Unicode encoding, so we don't it for C++. Characters are encoded as |