--- libiberty/cp-demangle.h | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/libiberty/cp-demangle.h b/libiberty/cp-demangle.h index 6fce025..c37a91f 100644 --- a/libiberty/cp-demangle.h +++ b/libiberty/cp-demangle.h @@ -135,12 +135,41 @@ struct d_info - call d_check_char(di, '\0') Everything else is safe. */ #define d_peek_char(di) (*((di)->n)) -#define d_peek_next_char(di) ((di)->n[1]) -#define d_advance(di, i) ((di)->n += (i)) +#ifndef CHECK_DEMANGLER +# define d_peek_next_char(di) ((di)->n[1]) +# define d_advance(di, i) ((di)->n += (i)) +#endif #define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0) #define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++)) #define d_str(di) ((di)->n) +/* Define CHECK_DEMANGLER to perform additional sanity checks (i.e., when + debugging the demangler). It will cause some slowdown, but will allow to + catch out-of-bound access errors earlier. + Note: CHECK_DEMANGLER is not compatible with compilers other than GCC. */ +#ifdef CHECK_DEMANGLER +static inline char +d_peek_next_char (const struct d_info *di) +{ + if (!di->n[0]) + __builtin_abort (); + return di->n[1]; +} + +static inline void +d_advance (struct d_info *di, int i) +{ + if (i < 0) + __builtin_abort (); + while (i--) + { + if (!di->n[0]) + __builtin_abort (); + di->n++; + } +} +#endif + /* Functions and arrays in cp-demangle.c which are referenced by functions in cp-demint.c. */ #ifdef IN_GLIBCPP_V3 -- 1.8.3.1