aboutsummaryrefslogtreecommitdiff
path: root/libiberty/cplus-dem.c
diff options
context:
space:
mode:
Diffstat (limited to 'libiberty/cplus-dem.c')
-rw-r--r--libiberty/cplus-dem.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index 6d58bd8..48c0cfd 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -146,6 +146,7 @@ struct work_stuff
int *proctypevec; /* Indices of currently processed remembered typevecs. */
int proctypevec_size;
int nproctypes;
+ unsigned int recursion_level;
};
#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
@@ -1292,12 +1293,14 @@ squangle_mop_up (struct work_stuff *work)
free ((char *) work -> btypevec);
work->btypevec = NULL;
work->bsize = 0;
+ work->numb = 0;
}
if (work -> ktypevec != NULL)
{
free ((char *) work -> ktypevec);
work->ktypevec = NULL;
work->ksize = 0;
+ work->numk = 0;
}
}
@@ -1331,8 +1334,15 @@ work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from)
for (i = 0; i < from->numk; i++)
{
- int len = strlen (from->ktypevec[i]) + 1;
+ int len;
+ if (from->ktypevec[i] == NULL)
+ {
+ to->ktypevec[i] = NULL;
+ continue;
+ }
+
+ len = strlen (from->ktypevec[i]) + 1;
to->ktypevec[i] = XNEWVEC (char, len);
memcpy (to->ktypevec[i], from->ktypevec[i], len);
}
@@ -1342,8 +1352,15 @@ work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from)
for (i = 0; i < from->numb; i++)
{
- int len = strlen (from->btypevec[i]) + 1;
+ int len;
+ if (from->btypevec[i] == NULL)
+ {
+ to->btypevec[i] = NULL;
+ continue;
+ }
+
+ len = strlen (from->btypevec[i]) + 1;
to->btypevec[i] = XNEWVEC (char , len);
memcpy (to->btypevec[i], from->btypevec[i], len);
}
@@ -1401,6 +1418,7 @@ delete_non_B_K_work_stuff (struct work_stuff *work)
free ((char*) work->tmpl_argvec);
work->tmpl_argvec = NULL;
+ work->ntmpl_args = 0;
}
if (work->previous_argument)
{
@@ -4471,12 +4489,14 @@ remember_Btype (struct work_stuff *work, const char *start,
char *tem;
tem = XNEWVEC (char, len + 1);
- memcpy (tem, start, len);
+ if (len > 0)
+ memcpy (tem, start, len);
tem[len] = '\0';
work -> btypevec[index] = tem;
}
/* Lose all the info related to B and K type codes. */
+
static void
forget_B_and_K_types (struct work_stuff *work)
{
@@ -4502,6 +4522,7 @@ forget_B_and_K_types (struct work_stuff *work)
}
}
}
+
/* Forget the remembered types, but not the type vector itself. */
static void
@@ -4696,6 +4717,16 @@ demangle_nested_args (struct work_stuff *work, const char **mangled,
int result;
int saved_nrepeats;
+ if ((work->options & DMGL_NO_RECURSE_LIMIT) == 0)
+ {
+ if (work->recursion_level > DEMANGLE_RECURSION_LIMIT)
+ /* FIXME: There ought to be a way to report
+ that the recursion limit has been reached. */
+ return 0;
+
+ work->recursion_level ++;
+ }
+
/* The G++ name-mangling algorithm does not remember types on nested
argument lists, unless -fsquangling is used, and in that case the
type vector updated by remember_type is not used. So, we turn
@@ -4722,6 +4753,9 @@ demangle_nested_args (struct work_stuff *work, const char **mangled,
--work->forgetting_types;
work->nrepeats = saved_nrepeats;
+ if ((work->options & DMGL_NO_RECURSE_LIMIT) == 0)
+ --work->recursion_level;
+
return result;
}