diff options
-rw-r--r-- | libiberty/ChangeLog | 8 | ||||
-rw-r--r-- | libiberty/d-demangle.c | 104 | ||||
-rw-r--r-- | libiberty/testsuite/d-demangle-expected | 120 |
3 files changed, 185 insertions, 47 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index fa2104dc866..9bf22362cdb 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,5 +1,13 @@ 2017-05-02 Iain Buclaw <ibuclaw@gdcproject.org> + * d-demangle.c (strtol): Remove declaration. + Updated all callers to use dlang_number. + (dlang_number): New function. + (dlang_value): Moved check for ISDIGIT into dlang_parse_integer. + * testsuite/d-demangle-expected: Add tests. + +2017-05-02 Iain Buclaw <ibuclaw@gdcproject.org> + * d-demangle.c (dlang_parse_symbol): Remove function. (dlang_parse_qualified): New function. (dlang_parse_mangle): New function. diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c index f62cc63878c..3aaffe1f14f 100644 --- a/libiberty/d-demangle.c +++ b/libiberty/d-demangle.c @@ -26,9 +26,7 @@ You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If not, see <http://www.gnu.org/licenses/>. */ -/* This file exports one function; dlang_demangle. - - This file imports strtol for decoding mangled literals. */ +/* This file exports one function; dlang_demangle. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -42,8 +40,6 @@ If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_STDLIB_H #include <stdlib.h> -#else -extern long strtol (const char *nptr, char **endptr, int base); #endif #include <demangle.h> @@ -197,6 +193,36 @@ static const char *dlang_parse_tuple (string *, const char *); static const char *dlang_parse_template (string *, const char *, long); +/* Extract the number from MANGLED, and assign the result to RET. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_number (const char *mangled, long *ret) +{ + /* Return NULL if trying to extract something that isn't a digit. */ + if (mangled == NULL || !ISDIGIT (*mangled)) + return NULL; + + (*ret) = 0; + + while (ISDIGIT (*mangled)) + { + (*ret) *= 10; + + /* If an overflow occured when multiplying by ten, the result + will not be a multiple of ten. */ + if ((*ret % 10) != 0) + return NULL; + + (*ret) += mangled[0] - '0'; + mangled++; + } + + if (*mangled == '\0' || *ret < 0) + return NULL; + + return mangled; +} + /* Demangle the calling convention from MANGLED and append it to DECL. Return the remaining string on success or NULL on failure. */ static const char * @@ -709,15 +735,10 @@ static const char * dlang_identifier (string *decl, const char *mangled, enum dlang_symbol_kinds kind) { - char *endptr; long len; + const char *endptr = dlang_number (mangled, &len); - if (mangled == NULL || *mangled == '\0') - return NULL; - - len = strtol (mangled, &endptr, 10); - - if (endptr == NULL || len <= 0) + if (endptr == NULL || len == 0) return NULL; /* In template parameter symbols, the first character of the mangled @@ -726,7 +747,7 @@ dlang_identifier (string *decl, const char *mangled, if (kind == dlang_template_param) { long psize = len; - char *pend; + const char *pend; int saved = string_length (decl); /* Work backwards until a match is found. */ @@ -871,10 +892,10 @@ dlang_parse_integer (string *decl, const char *mangled, char type) char value[10]; int pos = 10; int width = 0; - char *endptr; - long val = strtol (mangled, &endptr, 10); + long val; - if (endptr == NULL || val < 0) + mangled = dlang_number (mangled, &val); + if (mangled == NULL) return NULL; string_append (decl, "'"); @@ -923,19 +944,17 @@ dlang_parse_integer (string *decl, const char *mangled, char type) string_appendn (decl, &(value[pos]), 10 - pos); } string_append (decl, "'"); - mangled = endptr; } else if (type == 'b') { /* Parse boolean value. */ - char *endptr; - long val = strtol (mangled, &endptr, 10); + long val; - if (endptr == NULL || val < 0) + mangled = dlang_number (mangled, &val); + if (mangled == NULL) return NULL; string_append (decl, val ? "true" : "false"); - mangled = endptr; } else { @@ -943,6 +962,9 @@ dlang_parse_integer (string *decl, const char *mangled, char type) const char *numptr = mangled; size_t num = 0; + if (! ISDIGIT (*mangled)) + return NULL; + while (ISDIGIT (*mangled)) { num++; @@ -1070,17 +1092,11 @@ static const char * dlang_parse_string (string *decl, const char *mangled) { char type = *mangled; - char *endptr; long len; mangled++; - len = strtol (mangled, &endptr, 10); - - if (endptr == NULL || len < 0) - return NULL; - - mangled = endptr; - if (*mangled != '_') + mangled = dlang_number (mangled, &len); + if (mangled == NULL || *mangled != '_') return NULL; mangled++; @@ -1143,13 +1159,12 @@ dlang_parse_string (string *decl, const char *mangled) static const char * dlang_parse_arrayliteral (string *decl, const char *mangled) { - char *endptr; - long elements = strtol (mangled, &endptr, 10); + long elements; - if (endptr == NULL || elements < 0) + mangled = dlang_number (mangled, &elements); + if (mangled == NULL) return NULL; - mangled = endptr; string_append (decl, "["); while (elements--) { @@ -1167,13 +1182,12 @@ dlang_parse_arrayliteral (string *decl, const char *mangled) static const char * dlang_parse_assocarray (string *decl, const char *mangled) { - char *endptr; - long elements = strtol (mangled, &endptr, 10); + long elements; - if (endptr == NULL || elements < 0) + mangled = dlang_number (mangled, &elements); + if (mangled == NULL) return NULL; - mangled = endptr; string_append (decl, "["); while (elements--) { @@ -1194,13 +1208,12 @@ dlang_parse_assocarray (string *decl, const char *mangled) static const char * dlang_parse_structlit (string *decl, const char *mangled, const char *name) { - char *endptr; - long args = strtol (mangled, &endptr, 10); + long args; - if (endptr == NULL || args < 0) + mangled = dlang_number (mangled, &args); + if (mangled == NULL) return NULL; - mangled = endptr; if (name != NULL) string_append (decl, name); @@ -1241,8 +1254,6 @@ dlang_value (string *decl, const char *mangled, const char *name, char type) case 'i': mangled++; - if (*mangled < '0' || *mangled > '9') - return NULL; /* Fall through */ /* There really should always be an `i' before encoded numbers, but there @@ -1469,13 +1480,12 @@ dlang_parse_qualified (string *decl, const char *mangled, static const char * dlang_parse_tuple (string *decl, const char *mangled) { - char *endptr; - long elements = strtol (mangled, &endptr, 10); + long elements; - if (endptr == NULL || elements < 0) + mangled = dlang_number (mangled, &elements); + if (mangled == NULL) return NULL; - mangled = endptr; string_append (decl, "Tuple!("); while (elements--) diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected index 76cb208c81b..0f511475faf 100644 --- a/libiberty/testsuite/d-demangle-expected +++ b/libiberty/testsuite/d-demangle-expected @@ -850,6 +850,14 @@ _D8demangle22__T4testVG3uw3_616263Zv demangle.test!("abc"w) # --format=dlang +_D8demangle16__T4testVAyaa0_Zv +demangle.test!("") +# +--format=dlang +_D8demangle30__T4testVAyaa7_20090a0d0c0b00Zv +demangle.test!(" \t\n\r\f\v\x00") +# +--format=dlang _D8demangle22__T4testVAiA4i1i2i3i4Zv demangle.test!([1, 2, 3, 4]) # @@ -964,6 +972,118 @@ _D5__T1aZv _D5__T1aZv # --format=dlang +_D00 +_D00 +# +--format=dlang +_D9223372036854775817 +_D9223372036854775817 +# +--format=dlang +_D1az +_D1az +# +--format=dlang +_D1aN +_D1aN +# +--format=dlang +_D1aF +_D1aF +# +--format=dlang +_D1aM +_D1aM +# +--format=dlang +_D1aFZNz +_D1aFZNz +# +--format=dlang +_D1aFNzZv +_D1aFNzZv +# +--format=dlang +_D4testFDX +_D4testFDX +# +--format=dlang +_D5__T0aZv +_D5__T0aZv +# +--format=dlang +_D10__T4testYZv +_D10__T4testYZv +# +--format=dlang +_D4testFBaZv +_D4testFBaZv +# +--format=dlang +_D8__T4test +_D8__T4test +# +--format=dlang +_D10__T4testVi +_D10__T4testVi +# +--format=dlang +_D10__T4testVai +_D10__T4testVai +# +--format=dlang +_D10__T4testVbi +_D10__T4testVbi +# +--format=dlang +_D11__T4testS1a +_D11__T4testS1a +# +--format=dlang +_D12__T4testViiZv +_D12__T4testViiZv +# +--format=dlang +_D12__T4testViYZv +_D12__T4testViYZv +# +--format=dlang +_D12__T4testVrcZv +_D12__T4testVrcZv +# +--format=dlang +_D13__T4testVdeYZv +_D13__T4testVdeYZv +# +--format=dlang +_D13__T4testViSiZv +_D13__T4testViSiZv +# +--format=dlang +_D14__T4testVAiAiZv +_D14__T4testVAiAiZv +# +--format=dlang +_D14__T4testS123aZv +_D14__T4testS123aZv +# +--format=dlang +_D15__T4testVHiiAiZv +_D15__T4testVHiiAiZv +# +--format=dlang +_D15__T4testVfe0p1Zv +_D15__T4testVfe0p1Zv +# +--format=dlang +_D16__T4testVAyaa0aZv +_D16__T4testVAyaa0aZv +# +--format=dlang +_D18__T4testVAyaa1_YYZv +_D18__T4testVAyaa1_YYZv +# +--format=dlang _D4test3fooAa test.foo # |