From 7ade7fba756326c5f35f53a8e2d46443c6bab73f Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 8 Sep 2020 18:57:15 +0930 Subject: sync libiberty from gcc config/ Sync from gcc 2020-07-15 H.J. Lu PR bootstrap/96202 * cet.m4 (GCC_CET_HOST_FLAGS): Don't enable CET without CET support in stage1 nor for build support. libiberty/ * configure: Regenerate. Sync from gcc 2020-09-08 Alan Modra * d-demangle.c: Include limits.h. (ULONG_MAX, UINT_MAX): Provide fall-back definition. (dlang_number): Simplify and correct overflow test. Only write *ret on returning non-NULL. Make "ret" an unsigned long*. Only succeed for result of [0,UINT_MAX]. (dlang_decode_backref): Simplify and correct overflow test. Only write *ret on returning non-NULL. Only succeed for result [1,MAX_LONG]. (dlang_backref): Remove now unnecessary range check. (dlang_symbol_name_p): Likewise. (string_need): Take a size_t n arg, and use size_t tem. (string_append): Use size_t n. (string_appendn, string_prependn): Take a size_t n arg. (TEMPLATE_LENGTH_UNKNOWN): Define as -1UL. (dlang_lname, dlang_parse_template): Take an unsigned long len arg. (dlang_symbol_backref, dlang_identifier, dlang_parse_integer), (dlang_parse_integer, dlang_parse_string), (dlang_parse_arrayliteral, dlang_parse_assocarray), (dlang_parse_structlit, dlang_parse_tuple), (dlang_template_symbol_param, dlang_template_args): Use unsigned long variables. * testsuite/d-demangle-expected: Add new tests. 2020-08-04 Iain Buclaw * d-demangle.c (dlang_function_args): Handle 'in' and 'in ref' parameter storage classes. (dlang_type): Remove identifier type. * testsuite/d-demangle-expected: Update tests. 2020-08-03 Richard Biener PR lto/96385 * simple-object-elf.c (simple_object_elf_copy_lto_debug_sections): Localize global UNDEFs and reuse the prevailing name. 2020-07-10 Ian Lance Taylor PR demangler/96143 * cp-demangle.c (d_lambda): Don't add substitution candidate. * testsuite/demangle-expected: Update a few existing test cases accordingly, and add a new test case. 2020-07-04 Jason Merrill * cp-demangle.c (cplus_demangle_operators): Add di, dx, dX. (d_expression_1): Handle di and dX. (is_designated_init, d_maybe_print_designated_init): New. (d_print_comp_inner): Use d_maybe_print_designated_init. * testsuite/demangle-expected: Add designator tests. 2020-06-25 Nick Clifton * bsearch.c (bsearch): Remove use of register keyword. * bsearch_r.c (bsearch_r): Likewise. --- config/ChangeLog | 8 +++ config/cet.m4 | 23 +++++-- libiberty/ChangeLog | 59 ++++++++++++++++ libiberty/bsearch.c | 12 ++-- libiberty/bsearch_r.c | 12 ++-- libiberty/configure | 21 ++++-- libiberty/cp-demangle.c | 80 ++++++++++++++++++++-- libiberty/d-demangle.c | 116 +++++++++++++++++++------------- libiberty/simple-object-elf.c | 5 ++ libiberty/testsuite/d-demangle-expected | 24 ++++--- libiberty/testsuite/demangle-expected | 23 +++++-- 11 files changed, 299 insertions(+), 84 deletions(-) diff --git a/config/ChangeLog b/config/ChangeLog index ba1fc7f..a6454d3 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,3 +1,11 @@ +2020-09-08 Alan Modra + + Sync from gcc + 2020-07-15 H.J. Lu + PR bootstrap/96202 + * cet.m4 (GCC_CET_HOST_FLAGS): Don't enable CET without CET + support in stage1 nor for build support. + 2020-07-30 Rainer Orth * largefile.m4 (ACX_LARGEFILE) : diff --git a/config/cet.m4 b/config/cet.m4 index 911fbd4..c67fb4f 100644 --- a/config/cet.m4 +++ b/config/cet.m4 @@ -13,7 +13,7 @@ case "$host" in case "$enable_cet" in auto) # Check if target supports multi-byte NOPs - # and if assembler supports CET insn. + # and if compiler and assembler support CET insn. cet_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fcf-protection" AC_COMPILE_IFELSE( @@ -70,7 +70,7 @@ case "$host" in case "$enable_cet" in auto) # Check if target supports multi-byte NOPs - # and if assembler supports CET insn. + # and if compiler and assembler support CET. AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [], @@ -85,13 +85,26 @@ asm ("setssbsy"); [enable_cet=no]) ;; yes) - # Check if assembler supports CET. + # Check if compiler and assembler support CET. AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [], [asm ("setssbsy");])], - [], - [AC_MSG_ERROR([assembler with CET support is required for --enable-cet])]) + [support_cet=yes], + [support_cet=no]) + if test $support_cet = "no"; then + if test x$enable_bootstrap != xno \ + && test -z "${with_build_subdir}" \ + && (test ! -f ../stage_current \ + || test `cat ../stage_current` != "stage1"); then + # Require CET support only for the final GCC build. + AC_MSG_ERROR([compiler and assembler with CET support are required for --enable-cet]) + else + # Don't enable CET without CET support for non-bootstrap + # build, in stage1 nor for build support. + enable_cet=no + fi + fi ;; esac CFLAGS="$cet_save_CFLAGS" diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 19d2b70..6b46642 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,62 @@ +2020-09-08 Alan Modra + + * configure: Regenerate. + + Sync from gcc + 2020-09-08 Alan Modra + * d-demangle.c: Include limits.h. + (ULONG_MAX, UINT_MAX): Provide fall-back definition. + (dlang_number): Simplify and correct overflow test. Only + write *ret on returning non-NULL. Make "ret" an unsigned long*. + Only succeed for result of [0,UINT_MAX]. + (dlang_decode_backref): Simplify and correct overflow test. + Only write *ret on returning non-NULL. Only succeed for + result [1,MAX_LONG]. + (dlang_backref): Remove now unnecessary range check. + (dlang_symbol_name_p): Likewise. + (string_need): Take a size_t n arg, and use size_t tem. + (string_append): Use size_t n. + (string_appendn, string_prependn): Take a size_t n arg. + (TEMPLATE_LENGTH_UNKNOWN): Define as -1UL. + (dlang_lname, dlang_parse_template): Take an unsigned long len + arg. + (dlang_symbol_backref, dlang_identifier, dlang_parse_integer), + (dlang_parse_integer, dlang_parse_string), + (dlang_parse_arrayliteral, dlang_parse_assocarray), + (dlang_parse_structlit, dlang_parse_tuple), + (dlang_template_symbol_param, dlang_template_args): Use + unsigned long variables. + * testsuite/d-demangle-expected: Add new tests. + + 2020-08-04 Iain Buclaw + * d-demangle.c (dlang_function_args): Handle 'in' and 'in ref' + parameter storage classes. + (dlang_type): Remove identifier type. + * testsuite/d-demangle-expected: Update tests. + + 2020-08-03 Richard Biener + PR lto/96385 + * simple-object-elf.c + (simple_object_elf_copy_lto_debug_sections): Localize global + UNDEFs and reuse the prevailing name. + + 2020-07-10 Ian Lance Taylor + PR demangler/96143 + * cp-demangle.c (d_lambda): Don't add substitution candidate. + * testsuite/demangle-expected: Update a few existing test cases + accordingly, and add a new test case. + + 2020-07-04 Jason Merrill + * cp-demangle.c (cplus_demangle_operators): Add di, dx, dX. + (d_expression_1): Handle di and dX. + (is_designated_init, d_maybe_print_designated_init): New. + (d_print_comp_inner): Use d_maybe_print_designated_init. + * testsuite/demangle-expected: Add designator tests. + + 2020-06-25 Nick Clifton + * bsearch.c (bsearch): Remove use of register keyword. + * bsearch_r.c (bsearch_r): Likewise. + 2020-06-23 Nick Alcock * bsearch_r.c: New file. diff --git a/libiberty/bsearch.c b/libiberty/bsearch.c index 35fad19..18158b9 100644 --- a/libiberty/bsearch.c +++ b/libiberty/bsearch.c @@ -69,13 +69,13 @@ is respectively less than, matching, or greater than the array member. * look at item 3. */ void * -bsearch (register const void *key, const void *base0, - size_t nmemb, register size_t size, - register int (*compar)(const void *, const void *)) +bsearch (const void *key, const void *base0, + size_t nmemb, size_t size, + int (*compar)(const void *, const void *)) { - register const char *base = (const char *) base0; - register int lim, cmp; - register const void *p; + const char *base = (const char *) base0; + int lim, cmp; + const void *p; for (lim = nmemb; lim != 0; lim >>= 1) { p = base + (lim >> 1) * size; diff --git a/libiberty/bsearch_r.c b/libiberty/bsearch_r.c index 79ebae9..2a2ca6f 100644 --- a/libiberty/bsearch_r.c +++ b/libiberty/bsearch_r.c @@ -70,14 +70,14 @@ is respectively less than, matching, or greater than the array member. * look at item 3. */ void * -bsearch_r (register const void *key, const void *base0, - size_t nmemb, register size_t size, - register int (*compar)(const void *, const void *, void *), +bsearch_r (const void *key, const void *base0, + size_t nmemb, size_t size, + int (*compar)(const void *, const void *, void *), void *arg) { - register const char *base = (const char *) base0; - register int lim, cmp; - register const void *p; + const char *base = (const char *) base0; + int lim, cmp; + const void *p; for (lim = nmemb; lim != 0; lim >>= 1) { p = base + (lim >> 1) * size; diff --git a/libiberty/configure b/libiberty/configure index 1f8e23f..ff93c9e 100755 --- a/libiberty/configure +++ b/libiberty/configure @@ -5291,7 +5291,7 @@ case "$host" in case "$enable_cet" in auto) # Check if target supports multi-byte NOPs - # and if assembler supports CET insn. + # and if compiler and assembler support CET. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -5317,7 +5317,7 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ;; yes) - # Check if assembler supports CET. + # Check if compiler and assembler support CET. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -5330,11 +5330,24 @@ asm ("setssbsy"); } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - + support_cet=yes else - as_fn_error $? "assembler with CET support is required for --enable-cet" "$LINENO" 5 + support_cet=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $support_cet = "no"; then + if test x$enable_bootstrap != xno \ + && test -z "${with_build_subdir}" \ + && (test ! -f ../stage_current \ + || test `cat ../stage_current` != "stage1"); then + # Require CET support only for the final GCC build. + as_fn_error $? "compiler and assembler with CET support are required for --enable-cet" "$LINENO" 5 + else + # Don't enable CET without CET support for non-bootstrap + # build, in stage1 nor for build support. + enable_cet=no + fi + fi ;; esac CFLAGS="$cet_save_CFLAGS" diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index cbfb2f9..aede23f 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -1809,13 +1809,16 @@ const struct demangle_operator_info cplus_demangle_operators[] = { "cm", NL (","), 2 }, { "co", NL ("~"), 1 }, { "dV", NL ("/="), 2 }, + { "dX", NL ("[...]="), 3 }, /* [expr...expr] = expr */ { "da", NL ("delete[] "), 1 }, { "dc", NL ("dynamic_cast"), 2 }, { "de", NL ("*"), 1 }, + { "di", NL ("="), 2 }, /* .name = expr */ { "dl", NL ("delete "), 1 }, { "ds", NL (".*"), 2 }, { "dt", NL ("."), 2 }, { "dv", NL ("/"), 2 }, + { "dx", NL ("]="), 2 }, /* [expr] = expr */ { "eO", NL ("^="), 2 }, { "eo", NL ("^"), 2 }, { "eq", NL ("=="), 2 }, @@ -3291,6 +3294,12 @@ op_is_new_cast (struct demangle_component *op) ::= sr ::= sr ::= + + ::= + ::= di # .name = expr + ::= dx # [expr] = expr + ::= dX + # [expr ... expr] = expr */ static inline struct demangle_component * @@ -3453,6 +3462,8 @@ d_expression_1 (struct d_info *di) else if (code[0] == 'f') /* fold-expression. */ left = d_operator_name (di); + else if (!strcmp (code, "di")) + left = d_unqualified_name (di); else left = d_expression_1 (di); if (!strcmp (code, "cl")) @@ -3480,7 +3491,8 @@ d_expression_1 (struct d_info *di) if (code == NULL) return NULL; - else if (!strcmp (code, "qu")) + else if (!strcmp (code, "qu") + || !strcmp (code, "dX")) { /* ?: expression. */ first = d_expression_1 (di); @@ -3764,9 +3776,6 @@ d_lambda (struct d_info *di) ret->u.s_unary_num.num = num; } - if (! d_add_substitution (di, ret)) - return NULL; - return ret; } @@ -4675,6 +4684,64 @@ d_maybe_print_fold_expression (struct d_print_info *dpi, int options, return 1; } +/* True iff DC represents a C99-style designated initializer. */ + +static int +is_designated_init (struct demangle_component *dc) +{ + if (dc->type != DEMANGLE_COMPONENT_BINARY + && dc->type != DEMANGLE_COMPONENT_TRINARY) + return 0; + + struct demangle_component *op = d_left (dc); + const char *code = op->u.s_operator.op->code; + return (code[0] == 'd' + && (code[1] == 'i' || code[1] == 'x' || code[1] == 'X')); +} + +/* If DC represents a C99-style designated initializer, print it and return + true; otherwise, return false. */ + +static int +d_maybe_print_designated_init (struct d_print_info *dpi, int options, + struct demangle_component *dc) +{ + if (!is_designated_init (dc)) + return 0; + + const char *code = d_left (dc)->u.s_operator.op->code; + + struct demangle_component *operands = d_right (dc); + struct demangle_component *op1 = d_left (operands); + struct demangle_component *op2 = d_right (operands); + + if (code[1] == 'i') + d_append_char (dpi, '.'); + else + d_append_char (dpi, '['); + + d_print_comp (dpi, options, op1); + if (code[1] == 'X') + { + d_append_string (dpi, " ... "); + d_print_comp (dpi, options, d_left (op2)); + op2 = d_right (op2); + } + if (code[1] != 'i') + d_append_char (dpi, ']'); + if (is_designated_init (op2)) + { + /* Don't put '=' or '(' between chained designators. */ + d_print_comp (dpi, options, op2); + } + else + { + d_append_char (dpi, '='); + d_print_subexpr (dpi, options, op2); + } + return 1; +} + /* Subroutine to handle components. */ static void @@ -5491,6 +5558,9 @@ d_print_comp_inner (struct d_print_info *dpi, int options, if (d_maybe_print_fold_expression (dpi, options, dc)) return; + if (d_maybe_print_designated_init (dpi, options, dc)) + return; + /* We wrap an expression which uses the greater-than operator in an extra layer of parens so that it does not get confused with the '>' which ends the template parameters. */ @@ -5548,6 +5618,8 @@ d_print_comp_inner (struct d_print_info *dpi, int options, } if (d_maybe_print_fold_expression (dpi, options, dc)) return; + if (d_maybe_print_designated_init (dpi, options, dc)) + return; { struct demangle_component *op = d_left (dc); struct demangle_component *first = d_left (d_right (dc)); diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c index f2d6946..cd3bc96 100644 --- a/libiberty/d-demangle.c +++ b/libiberty/d-demangle.c @@ -31,6 +31,9 @@ If not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#ifdef HAVE_LIMITS_H +#include +#endif #include "safe-ctype.h" @@ -45,6 +48,13 @@ If not, see . */ #include #include "libiberty.h" +#ifndef ULONG_MAX +#define ULONG_MAX (~0UL) +#endif +#ifndef UINT_MAX +#define UINT_MAX (~0U) +#endif + /* A mini string-handling package */ typedef struct string /* Beware: these aren't required to be */ @@ -55,9 +65,9 @@ typedef struct string /* Beware: these aren't required to be */ } string; static void -string_need (string *s, int n) +string_need (string *s, size_t n) { - int tem; + size_t tem; if (s->b == NULL) { @@ -68,7 +78,7 @@ string_need (string *s, int n) s->p = s->b = XNEWVEC (char, n); s->e = s->b + n; } - else if (s->e - s->p < n) + else if ((size_t) (s->e - s->p) < n) { tem = s->p - s->b; n += tem; @@ -117,14 +127,14 @@ string_setlength (string *s, int n) static void string_append (string *p, const char *s) { - int n = strlen (s); + size_t n = strlen (s); string_need (p, n); memcpy (p->p, s, n); p->p += n; } static void -string_appendn (string *p, const char *s, int n) +string_appendn (string *p, const char *s, size_t n) { if (n != 0) { @@ -135,7 +145,7 @@ string_appendn (string *p, const char *s, int n) } static void -string_prependn (string *p, const char *s, int n) +string_prependn (string *p, const char *s, size_t n) { char *q; @@ -170,7 +180,7 @@ struct dlang_info }; /* Pass as the LEN to dlang_parse_template if symbol length is not known. */ -enum { TEMPLATE_LENGTH_UNKNOWN = -1 }; +#define TEMPLATE_LENGTH_UNKNOWN (-1UL) /* Prototypes for forward referenced functions */ static const char *dlang_function_type (string *, const char *, @@ -193,38 +203,39 @@ static const char *dlang_parse_tuple (string *, const char *, struct dlang_info *); static const char *dlang_parse_template (string *, const char *, - struct dlang_info *, long); + struct dlang_info *, unsigned long); -static const char *dlang_lname (string *, const char *, long); +static const char *dlang_lname (string *, const char *, unsigned long); /* Extract the number from MANGLED, and assign the result to RET. - Return the remaining string on success or NULL on failure. */ + Return the remaining string on success or NULL on failure. + A result larger than UINT_MAX is considered a failure. */ static const char * -dlang_number (const char *mangled, long *ret) +dlang_number (const char *mangled, unsigned long *ret) { /* Return NULL if trying to extract something that isn't a digit. */ if (mangled == NULL || !ISDIGIT (*mangled)) return NULL; - (*ret) = 0; + unsigned long val = 0; while (ISDIGIT (*mangled)) { - (*ret) *= 10; + unsigned long digit = mangled[0] - '0'; - /* If an overflow occured when multiplying by ten, the result - will not be a multiple of ten. */ - if ((*ret % 10) != 0) + /* Check for overflow. */ + if (val > (UINT_MAX - digit) / 10) return NULL; - (*ret) += mangled[0] - '0'; + val = val * 10 + digit; mangled++; } - if (*mangled == '\0' || *ret < 0) + if (*mangled == '\0') return NULL; + *ret = val; return mangled; } @@ -273,7 +284,8 @@ dlang_call_convention_p (const char *mangled) } /* Extract the back reference position from MANGLED, and assign the result - to RET. Return the remaining string on success or NULL on failure. */ + to RET. Return the remaining string on success or NULL on failure. + A result <= 0 is a failure. */ static const char * dlang_decode_backref (const char *mangled, long *ret) { @@ -294,24 +306,26 @@ dlang_decode_backref (const char *mangled, long *ret) [A-Z] NumberBackRef ^ */ - (*ret) = 0; + unsigned long val = 0; while (ISALPHA (*mangled)) { - (*ret) *= 26; + /* Check for overflow. */ + if (val > (ULONG_MAX - 25) / 26) + break; - /* If an overflow occured when multiplying by 26, the result - will not be a multiple of 26. */ - if ((*ret % 26) != 0) - return NULL; + val *= 26; if (mangled[0] >= 'a' && mangled[0] <= 'z') { - (*ret) += mangled[0] - 'a'; + val += mangled[0] - 'a'; + if ((long) val <= 0) + break; + *ret = val; return mangled + 1; } - (*ret) += mangled[0] - 'A'; + val += mangled[0] - 'A'; mangled++; } @@ -337,7 +351,7 @@ dlang_backref (const char *mangled, const char **ret, struct dlang_info *info) if (mangled == NULL) return NULL; - if (refpos <= 0 || refpos > qpos - info->s) + if (refpos > qpos - info->s) return NULL; /* Set the position of the back reference. */ @@ -359,7 +373,7 @@ dlang_symbol_backref (string *decl, const char *mangled, ^ */ const char *backref; - long len; + unsigned long len; /* Get position of the back reference. */ mangled = dlang_backref (mangled, &backref, info); @@ -435,7 +449,7 @@ dlang_symbol_name_p (const char *mangled, struct dlang_info *info) return 0; mangled = dlang_decode_backref (mangled + 1, &ret); - if (mangled == NULL || ret <= 0 || ret > qref - info->s) + if (mangled == NULL || ret > qref - info->s) return 0; return ISDIGIT (qref[-ret]); @@ -699,6 +713,15 @@ dlang_function_args (string *decl, const char *mangled, struct dlang_info *info) switch (*mangled) { + case 'I': /* in(T) */ + mangled++; + string_append (decl, "in "); + if (*mangled == 'K') /* in ref(T) */ + { + mangled++; + string_append (decl, "ref "); + } + break; case 'J': /* out(T) */ mangled++; string_append (decl, "out "); @@ -826,7 +849,6 @@ dlang_type (string *decl, const char *mangled, struct dlang_info *info) mangled = dlang_function_type (decl, mangled, info); string_append (decl, "function"); return mangled; - case 'I': /* ident T */ case 'C': /* class T */ case 'S': /* struct T */ case 'E': /* enum T */ @@ -985,7 +1007,7 @@ dlang_type (string *decl, const char *mangled, struct dlang_info *info) static const char * dlang_identifier (string *decl, const char *mangled, struct dlang_info *info) { - long len; + unsigned long len; if (mangled == NULL || *mangled == '\0') return NULL; @@ -1003,7 +1025,7 @@ dlang_identifier (string *decl, const char *mangled, struct dlang_info *info) if (endptr == NULL || len == 0) return NULL; - if (strlen (endptr) < (size_t) len) + if (strlen (endptr) < len) return NULL; mangled = endptr; @@ -1020,7 +1042,7 @@ dlang_identifier (string *decl, const char *mangled, struct dlang_info *info) with special treatment for some magic compiler generted symbols. Return the remaining string on success or NULL on failure. */ static const char * -dlang_lname (string *decl, const char *mangled, long len) +dlang_lname (string *decl, const char *mangled, unsigned long len) { switch (len) { @@ -1119,7 +1141,7 @@ dlang_parse_integer (string *decl, const char *mangled, char type) char value[20]; int pos = sizeof(value); int width = 0; - long val; + unsigned long val; mangled = dlang_number (mangled, &val); if (mangled == NULL) @@ -1175,7 +1197,7 @@ dlang_parse_integer (string *decl, const char *mangled, char type) else if (type == 'b') { /* Parse boolean value. */ - long val; + unsigned long val; mangled = dlang_number (mangled, &val); if (mangled == NULL) @@ -1294,7 +1316,7 @@ static const char * dlang_parse_string (string *decl, const char *mangled) { char type = *mangled; - long len; + unsigned long len; mangled++; mangled = dlang_number (mangled, &len); @@ -1358,7 +1380,7 @@ dlang_parse_string (string *decl, const char *mangled) static const char * dlang_parse_arrayliteral (string *decl, const char *mangled) { - long elements; + unsigned long elements; mangled = dlang_number (mangled, &elements); if (mangled == NULL) @@ -1384,7 +1406,7 @@ dlang_parse_arrayliteral (string *decl, const char *mangled) static const char * dlang_parse_assocarray (string *decl, const char *mangled) { - long elements; + unsigned long elements; mangled = dlang_number (mangled, &elements); if (mangled == NULL) @@ -1415,7 +1437,7 @@ dlang_parse_assocarray (string *decl, const char *mangled) static const char * dlang_parse_structlit (string *decl, const char *mangled, const char *name) { - long args; + unsigned long args; mangled = dlang_number (mangled, &args); if (mangled == NULL) @@ -1642,7 +1664,7 @@ dlang_parse_qualified (string *decl, const char *mangled, static const char * dlang_parse_tuple (string *decl, const char *mangled, struct dlang_info *info) { - long elements; + unsigned long elements; mangled = dlang_number (mangled, &elements); if (mangled == NULL) @@ -1677,7 +1699,7 @@ dlang_template_symbol_param (string *decl, const char *mangled, if (*mangled == 'Q') return dlang_parse_qualified (decl, mangled, info, 0); - long len; + unsigned long len; const char *endptr = dlang_number (mangled, &len); if (endptr == NULL || len == 0) @@ -1790,12 +1812,12 @@ dlang_template_args (string *decl, const char *mangled, struct dlang_info *info) } case 'X': /* Externally mangled parameter. */ { - long len; + unsigned long len; const char *endptr; mangled++; endptr = dlang_number (mangled, &len); - if (endptr == NULL || strlen (endptr) < (size_t) len) + if (endptr == NULL || strlen (endptr) < len) return NULL; string_appendn (decl, endptr, len); @@ -1815,7 +1837,7 @@ dlang_template_args (string *decl, const char *mangled, struct dlang_info *info) Returns the remaining signature on success or NULL on failure. */ static const char * dlang_parse_template (string *decl, const char *mangled, - struct dlang_info *info, long len) + struct dlang_info *info, unsigned long len) { const char *start = mangled; string args; @@ -1851,7 +1873,9 @@ dlang_parse_template (string *decl, const char *mangled, string_delete (&args); /* Check for template name length mismatch. */ - if (len != TEMPLATE_LENGTH_UNKNOWN && mangled && (mangled - start) != len) + if (len != TEMPLATE_LENGTH_UNKNOWN + && mangled + && (unsigned long) (mangled - start) != len) return NULL; return mangled; diff --git a/libiberty/simple-object-elf.c b/libiberty/simple-object-elf.c index c62d5bb..7c9d492 100644 --- a/libiberty/simple-object-elf.c +++ b/libiberty/simple-object-elf.c @@ -1467,6 +1467,11 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, && st_shndx < shnum && pfnret[st_shndx - 1] == -1) discard = 1; + /* We also need to remove global UNDEFs which can + cause link fails later. */ + else if (st_shndx == SHN_UNDEF + && ELF_ST_BIND (*st_info) == STB_GLOBAL) + discard = 1; if (discard) { diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected index e3f32e3..ba0ffed 100644 --- a/libiberty/testsuite/d-demangle-expected +++ b/libiberty/testsuite/d-demangle-expected @@ -274,14 +274,6 @@ _D8demangle4testFNhG4dZv demangle.test(__vector(double[4])) # --format=dlang -_D8demangle4testFI5identZv -demangle.test(ident) -# ---format=dlang -_D8demangle4testFI5ident4testZv -demangle.test(ident.test) -# ---format=dlang _D8demangle4testFC5classZv demangle.test(class) # @@ -314,6 +306,14 @@ _D8demangle4testFT7typedef4testZv demangle.test(typedef.test) # --format=dlang +_D8demangle4testFIaZv +demangle.test(in char) +# +--format=dlang +_D8demangle4testFIKaZv +demangle.test(in ref char) +# +--format=dlang _D8demangle4testFJaZv demangle.test(out char) # @@ -1140,6 +1140,14 @@ _D4test34__T3barVG3uw3_616263VG3wd3_646566Z1xi test.bar!("abc"w, "def"d).x # --format=dlang +_D4test21__T3funVwi4294967295Z3funFNaNbNiNfZv +test.fun!('\Uffffffff').fun() +# +--format=dlang +_D4test21__T3funVwi4294967296Z3funFNaNbNiNfZv +_D4test21__T3funVwi4294967296Z3funFNaNbNiNfZv +# +--format=dlang _D6plugin8generateFiiZAya plugin.generate(int, int) # diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index d8e5095..0850db3 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -1114,7 +1114,7 @@ DFA # http://sourceware.org/bugzilla/show_bug.cgi?id=11572 --format=auto _ZN3Psi7VariantIIcPKcEE5visitIIRZN11VariantTest9TestVisit11test_methodEvEUlS2_E0_RZNS6_11test_methodEvEUlcE1_RZNS6_11test_methodEvEUlNS_4NoneEE_EEENS_13VariantDetail19SelectVisitorResultIIDpT_EE4typeEDpOSG_ -Psi::VariantDetail::SelectVisitorResult::type Psi::Variant::visit((VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&)...) +Psi::VariantDetail::SelectVisitorResult::type Psi::Variant::visit(VariantTest::TestVisit::test_method()::{lambda(char const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&) # # Clone suffix tests # @@ -1170,7 +1170,7 @@ f # --format=gnu-v3 _ZN4modc6parser8sequenceINS_9astParser13LocatedParserINS0_9ParserRefINS2_UlRNS2_16TokenParserInputEE_EEEEEINS0_14OptionalParserINS2_18ListParserTemplateILNS_6tokens5Token4TypeE4EXadL_ZNSD_Ut_13parenthesizedEEEE6ParserINS4_INS0_6ParserIS5_NS_3ast10ExpressionEEEEEEEEENSA_INS4_INS2_22OneOfKeywordsToTParserINSJ_5StyleEEEEEEENS0_14SequenceParserIS5_INS0_18ExactElementParserIS5_EENSA_ISM_EEEEENS0_14RepeatedParserINS4_INS0_15TransformParserINSU_IS5_INS4_INSP_INSJ_10Annotation12RelationshipEEEEESX_EEENS2_UlNS2_3LocES12_ONS_5MaybeISK_EEE19_EEEEELb0EEEEEENSU_INS0_17ExtractParserTypeIT_E9InputTypeEINS0_8MaybeRefIS1F_E4TypeEDpNS1I_IT0_E4TypeEEEEOS1F_DpOS1L_ -modc::parser::ParserRef::Parser::Style> > > >::InputType, modc::parser::MaybeRef&&)#21}>::Type, modc::parser::RepeatedParser::Parser::Style> >::Parser > >::Parser::Annotation::Relationship> >, modc::parser::ExactElementParser> >, modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, modc::Maybe&&)#21}> >, false>::Parser > > > >::Type, modc::parser::RepeatedParser::Parser::Style> >::Parser > >::Parser::Annotation::Relationship> >, modc::parser::ExactElementParser> >, modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, modc::Maybe&&)#21}> >, false> >::Parser::Style> > > >::Type, modc::parser::RepeatedParser::Parser::Style> >::Parser > >::Parser::Annotation::Relationship> >, modc::parser::ExactElementParser> >, modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, modc::Maybe&&)#21}> >, false>, modc::astParser::LocatedParser > > > >::Type, modc::parser::RepeatedParser::Parser::Style> >::Parser > >::Parser::Annotation::Relationship> >, modc::parser::ExactElementParser> >, modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, modc::Maybe&&)#21}> >, false>::Parser::Style> >::Parser > >::Parser::Annotation::Relationship> >, modc::parser::ExactElementParser> >, modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, modc::Maybe&&)#21}> >, false> >::Type> modc::parser::sequence >, modc::parser::OptionalParser::Parser > > >, modc::astParser::LocatedParser >::Parser::Style> > >, modc::parser::SequenceParser, modc::astParser::LocatedParser > > >, modc::parser::RepeatedParser::Parser::Style> >::Parser > >::Parser::Annotation::Relationship> >, modc::parser::ExactElementParser> >, modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, modc::Maybe&&)#21}> >, false> >(modc::astParser::{lambda(modc::astParser::Loc, modc::parser::RepeatedParser, modc::Maybe&&)#21}&&, (modc::parser::ExtractParserType > >&&)...) +modc::parser::OptionalParser > > > >::InputType, modc::parser::MaybeRef > >::Parser > > > >, modc::parser::ExactElementParser > >, modc::astParser::{lambda(modc::astParser::Loc, modc::parser::TransformParser, modc::Maybe&&)#21}> > >::Type, modc::astParser::LocatedParser >::Parser > > > >::Type, modc::astParser::LocatedParser > > > >::Type, modc::astParser::LocatedParser >, modc::parser::OptionalParser > > > >::Type, modc::astParser::LocatedParser > > >::Parser > > > >, modc::parser::ExactElementParser > >, modc::astParser::{lambda(modc::astParser::Loc, modc::parser::TransformParser, modc::Maybe&&)#21}> >, false> >::Type> modc::parser::sequence >, modc::parser::OptionalParser::Parser > > >, modc::parser::OptionalParser > >, modc::parser::SequenceParser, modc::parser::OptionalParser > > >, modc::parser::RepeatedParser > >::Parser > > > >, modc::parser::ExactElementParser > >, modc::astParser::{lambda(modc::astParser::Loc, modc::parser::TransformParser, modc::Maybe&&)#21}> >, false> >(modc::parser::ParserRef > >::Parser > > > >, modc::parser::ExactElementParser > >, modc::astParser::{lambda(modc::astParser::Loc, modc::parser::TransformParser, modc::Maybe&&)#21}> >&&, (modc::parser::MaybeRef&&)...) --format=gnu-v3 _ZNKR1A1hEv A::h() const & @@ -1189,7 +1189,7 @@ void f() # https://sourceware.org/bugzilla/show_bug.cgi?id=14963#c3 --format=gnu-v3 _ZSt7forwardIRN1x14refobjiteratorINS0_3refINS0_4mime30multipart_section_processorObjIZ15get_body_parserIZZN14mime_processor21make_section_iteratorERKNS2_INS3_10sectionObjENS0_10ptrrefBaseEEEbENKUlvE_clEvEUlSB_bE_ZZNS6_21make_section_iteratorESB_bENKSC_clEvEUlSB_E0_ENS1_INS2_INS0_20outputrefiteratorObjIiEES8_EEEERKSsSB_OT_OT0_EUlmE_NS3_32make_multipart_default_discarderISP_EEEES8_EEEEEOT_RNSt16remove_referenceISW_E4typeE -x::refobjiterator const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}>(std::string const&, x::ref const&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}&&)::{lambda(unsigned long)#1}, x::mime::make_multipart_default_discarder const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&> >, x::ptrrefBase> >& std::forward const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}>(std::string const&, x::ref const&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}&&)::{lambda(unsigned long)#1}, x::mime::make_multipart_default_discarder const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&> >, x::ptrrefBase> >&>(std::remove_reference const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}>(std::string const&, x::ref const&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}&&)::{lambda(unsigned long)#1}, x::mime::make_multipart_default_discarder const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&> > >::type&) +x::refobjiterator const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}>(std::string const&, x::ref const&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}&&)::{lambda(unsigned long)#1}, x::mime::make_multipart_default_discarder const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}>(std::string const&, x::ref const&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}&&)::{lambda(unsigned long)#1}> >, x::ptrrefBase> >& std::forward const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}>(std::string const&, x::ref const&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}&&)::{lambda(unsigned long)#1}, x::mime::make_multipart_default_discarder const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}>(std::string const&, x::ref const&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}&&)::{lambda(unsigned long)#1}> >, x::ptrrefBase> >&>(std::remove_reference const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}>(std::string const&, x::ref const&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}&&)::{lambda(unsigned long)#1}, x::mime::make_multipart_default_discarder const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}>(std::string const&, x::ref const&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref const&)#2}&&)::{lambda(unsigned long)#1}> >, x::ptrrefBase> >&>::type&) # --format=gnu-v3 --no-params _ZNK7strings8internal8SplitterINS_9delimiter5AnyOfENS_9SkipEmptyEEcvT_ISt6vectorI12basic_stringIcSt11char_traitsIcESaIcEESaISD_EEvEEv @@ -1213,7 +1213,7 @@ A::operator C # https://sourceware.org/bugzilla/show_bug.cgi?id=14963#c16 --format=gnu-v3 _ZN3mdr16in_cached_threadIRZNK4cudr6GPUSet17parallel_for_eachIZN5tns3d20shape_representation7compute7GPUImpl7executeERKNS_1AINS_7ptr_refIKjEELl3ELl3ENS_8c_strideILl1ELl0EEEEERKNS8_INS9_IjEELl4ELl1ESD_EEEUliRKNS1_7ContextERNS7_5StateEE_JSt6vectorISO_SaISO_EEEEEvOT_DpRT0_EUlSP_E_JSt17reference_wrapperISO_EEEENS_12ScopedFutureIDTclfp_spcl7forwardISW_Efp0_EEEEESV_DpOSW_ -mdr::ScopedFuture, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}, std::vector > >(tns3d::shape_representation::compute::GPUImpl::execute(mdr::A, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}&&, std::vector >&) const::{lambda(tns3d::shape_representation::compute::GPUImpl::State&)#1}&>)({parm#2}))...))> mdr::in_cached_thread, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}, std::vector > >(cudr::GPUSet::parallel_for_each, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}, std::vector > >(tns3d::shape_representation::compute::GPUImpl::execute(mdr::A, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}&&, std::vector >&) const::{lambda(tns3d::shape_representation::compute::GPUImpl::State&)#1}&, std::vector >&) const::{lambda(tns3d::shape_representation::compute::GPUImpl::State&)#1}&, std::reference_wrapper >(cudr::GPUSet::parallel_for_each, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}, std::vector > >(tns3d::shape_representation::compute::GPUImpl::execute(mdr::A, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}&&, std::vector >&) const::{lambda(tns3d::shape_representation::compute::GPUImpl::State&)#1}&, (cudr::GPUSet::parallel_for_each, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}, std::vector > >(tns3d::shape_representation::compute::GPUImpl::execute(mdr::A, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}&&, std::vector >&) const::{lambda(tns3d::shape_representation::compute::GPUImpl::State&)#1}&&&)...) +mdr::ScopedFuture >)({parm#2})))> mdr::in_cached_thread, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}, std::vector > >(tns3d::shape_representation::compute::GPUImpl::execute(mdr::A, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}&&, std::vector >&) const::{lambda(tns3d::shape_representation::compute::GPUImpl::State&)#1}&, std::reference_wrapper >(tns3d::shape_representation::compute::GPUImpl::execute(mdr::A, 3l, 3l, mdr::c_stride<1l, 0l> > const&, mdr::A, 4l, 1l, mdr::c_stride<1l, 0l> > const&)::{lambda(int, cudr::Context const&, tns3d::shape_representation::compute::GPUImpl::State&)#1}&&, std::vector >&&) # https://sourceware.org/bugzilla/show_bug.cgi?id=14963#c18 --format=gnu-v3 _ZNSt9_Any_data9_M_accessIPZN13ThreadManager10futureTaskISt5_BindIFSt7_Mem_fnIM6RunnerFvvEEPS5_EEEEvOT_EUlvE_EERSC_v @@ -1269,7 +1269,7 @@ void function_temp(A) # --format=gnu-v3 _Z7ZipWithI7QStringS0_5QListZN4oral6detail16AdaptCreateTableI7AccountEES0_RKNS3_16CachedFieldsDataEEUlRKS0_SA_E_ET1_IDTclfp1_cvT__EcvT0__EEEERKT1_ISC_ERKT1_ISD_ET2_ -QList ZipWith(oral::detail::CachedFieldsData const&)::{lambda(QString const&, QString const&)#1}>(QList(oral::detail::CachedFieldsData const&)::{lambda(QString const&, QString const&)#1}> const&, QList const&, oral::detail::AdaptCreateTable(oral::detail::CachedFieldsData const&)::{lambda(QString const&, QString const&)#1}) +QList ZipWith(oral::detail::CachedFieldsData const&)::{lambda(QString const&, QString const&)#1}>(QList const&, QList const&, oral::detail::AdaptCreateTable(oral::detail::CachedFieldsData const&)::{lambda(QString const&, QString const&)#1}) # # These three are symbols generated by g++'s testsuite, which triggered the same bug as above. --format=gnu-v3 @@ -1456,3 +1456,16 @@ coro1::empty::operator co_await() const _ZNK3FoossERKS_ Foo::operator<=>(Foo const&) const + +_Z1f1AIXtl1Udi1iLi0EEEE +f(A) + +_Z1f1AIXtl1Xdi1adi1bdxLi3ELi1EEEE +f(A) + +_Z1f1AIXtl1Xdi1adi1bdXLi3ELi4ELi1EEEE +f(A) + +# PR 96143 +_Z2F2IZ1FvEUlvE_EN1AIT_E1XES2_ +A::X F2(F()::{lambda()#1}) -- cgit v1.1