diff --git a/include/demangle.h b/include/demangle.h index 4aedc338efe..6a03f4f4f93 100644 --- a/include/demangle.h +++ b/include/demangle.h @@ -448,6 +448,8 @@ enum demangle_component_type DEMANGLE_COMPONENT_TRANSACTION_SAFE, /* A cloned function. */ DEMANGLE_COMPONENT_CLONE, + /* A member-like friend function. */ + DEMANGLE_COMPONENT_FRIEND, DEMANGLE_COMPONENT_NOEXCEPT, DEMANGLE_COMPONENT_THROW_SPEC, @@ -464,6 +466,8 @@ enum demangle_component_type DEMANGLE_COMPONENT_TEMPLATE_TEMPLATE_PARM, DEMANGLE_COMPONENT_TEMPLATE_PACK_PARM, + DEMANGLE_COMPONENT_CONSTRAINTS, + /* A builtin type with argument. This holds the builtin type information. */ DEMANGLE_COMPONENT_EXTENDED_BUILTIN_TYPE diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 389fb14b96e..884c8b70f87 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -4,6 +4,21 @@ __get_cpuid_count are not implicitly declared. * configure: Regenerated. +2023-12-05 Rainer Orth + + * pex-unix.c (pex_unix_wait): Change return type to pid_t. + +2023-12-01 Jason Merrill + + * cp-demangle.c (d_make_comp): Handle + DEMANGLE_COMPONENT_CONSTRAINTS. + (d_count_templates_scopes): Likewise. + (d_print_comp_inner): Likewise. + (d_maybe_constraints): New. + (d_encoding, d_template_args_1): Call it. + (d_parmlist): Handle 'Q'. + * testsuite/demangle-expected: Add some constraint tests. + 2023-11-30 Rainer Orth * configure.ac (GCC_CHECK_ASSEMBLER_HWCAP): Invoke. @@ -20,6 +35,45 @@ * config.in: Regenerated. * configure: Regenerated. +2023-11-15 Mark Wielaard + + * aclocal.m4: Rebuild. + +2023-11-10 Brendan Shanks + + * configure.ac (AC_CHECK_HEADERS): Add spawn.h. + (checkfuncs): Add posix_spawn, posix_spawnp. + (AC_CHECK_FUNCS): Add posix_spawn, posix_spawnp. + * aclocal.m4, configure, config.in: Rebuild. + * pex-unix.c [HAVE_POSIX_SPAWN] (pex_unix_exec_child): New function. + +2023-08-22 Jason Merrill + + PR c++/109751 + * cp-demangle.c (d_make_comp): Handle DEMANGLE_COMPONENT_FRIEND. + (d_count_templates_scopes): Likewise. + (d_print_comp_inner): Likewise. + (d_unqualified_name): Handle member-like friend mangling. + * testsuite/demangle-expected: Add test. + +2023-08-07 John Ericson + + * configure: Regenerate. + +2023-08-07 H.J. Lu + + * configure: Regenerate. + +2023-08-07 H.J. Lu + + * Makefile.in (AR): Add @AR_PLUGIN_OPTION@ + (RANLIB): Add @RANLIB_PLUGIN_OPTION@. + (configure_deps): Depend on ../config/gcc-plugin.m4. + * configure.ac: AC_SUBST AR_PLUGIN_OPTION and + RANLIB_PLUGIN_OPTION. + * aclocal.m4: Regenerated. + * configure: Likewise. + 2023-06-15 Marek Polacek * configure.ac: Also set shared when enable_host_pie. diff --git a/libiberty/config.in b/libiberty/config.in index 6c4a2597e9e..1b1f2b09a8a 100644 --- a/libiberty/config.in +++ b/libiberty/config.in @@ -198,6 +198,12 @@ /* Define to 1 if you have the `pipe2' function. */ #undef HAVE_PIPE2 +/* Define to 1 if you have the `posix_spawn' function. */ +#undef HAVE_POSIX_SPAWN + +/* Define to 1 if you have the `posix_spawnp' function. */ +#undef HAVE_POSIX_SPAWNP + /* Define to 1 if you have the header file. */ #undef HAVE_PROCESS_H @@ -249,6 +255,9 @@ /* Define to 1 if you have the `spawnvpe' function. */ #undef HAVE_SPAWNVPE +/* Define to 1 if you have the header file. */ +#undef HAVE_SPAWN_H + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H diff --git a/libiberty/configure b/libiberty/configure index 291c910c9cf..5c69fee56c1 100755 --- a/libiberty/configure +++ b/libiberty/configure @@ -5746,7 +5746,7 @@ host_makefile_frag=${frag} # It's OK to check for header files. Although the compiler may not be # able to link anything, it had better be able to at least compile # something. -for ac_header in sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h stdio_ext.h process.h sys/prctl.h +for ac_header in sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h stdio_ext.h process.h sys/prctl.h spawn.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_preproc "$LINENO" "$ac_header" "$as_ac_Header" @@ -6255,7 +6255,8 @@ funcs="$funcs setproctitle" vars="sys_errlist sys_nerr sys_siglist" checkfuncs="__fsetlocking canonicalize_file_name dup3 getrlimit getrusage \ - getsysinfo gettimeofday on_exit pipe2 psignal pstat_getdynamic pstat_getstatic \ + getsysinfo gettimeofday on_exit pipe2 posix_spawn posix_spawnp psignal \ + pstat_getdynamic pstat_getstatic \ realpath setrlimit spawnve spawnvpe strerror strsignal sysconf sysctl \ sysmp table times wait3 wait4" @@ -6278,7 +6279,8 @@ if test "x" = "y"; then index insque \ memchr memcmp memcpy memmem memmove memset mkstemps \ on_exit \ - pipe2 psignal pstat_getdynamic pstat_getstatic putenv \ + pipe2 posix_spawn posix_spawnp psignal \ + pstat_getdynamic pstat_getstatic putenv \ random realpath rename rindex \ sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \ stpcpy stpncpy strcasecmp strchr strdup \ diff --git a/libiberty/configure.ac b/libiberty/configure.ac index 20e41859757..0888e638896 100644 --- a/libiberty/configure.ac +++ b/libiberty/configure.ac @@ -291,7 +291,7 @@ AC_SUBST_FILE(host_makefile_frag) # It's OK to check for header files. Although the compiler may not be # able to link anything, it had better be able to at least compile # something. -AC_CHECK_HEADERS(sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h stdio_ext.h process.h sys/prctl.h) +AC_CHECK_HEADERS(sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h stdio_ext.h process.h sys/prctl.h spawn.h) AC_HEADER_SYS_WAIT AC_HEADER_TIME @@ -414,7 +414,8 @@ funcs="$funcs setproctitle" vars="sys_errlist sys_nerr sys_siglist" checkfuncs="__fsetlocking canonicalize_file_name dup3 getrlimit getrusage \ - getsysinfo gettimeofday on_exit pipe2 psignal pstat_getdynamic pstat_getstatic \ + getsysinfo gettimeofday on_exit pipe2 posix_spawn posix_spawnp psignal \ + pstat_getdynamic pstat_getstatic \ realpath setrlimit spawnve spawnvpe strerror strsignal sysconf sysctl \ sysmp table times wait3 wait4" @@ -437,7 +438,8 @@ if test "x" = "y"; then index insque \ memchr memcmp memcpy memmem memmove memset mkstemps \ on_exit \ - pipe2 psignal pstat_getdynamic pstat_getstatic putenv \ + pipe2 posix_spawn posix_spawnp psignal \ + pstat_getdynamic pstat_getstatic putenv \ random realpath rename rindex \ sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \ stpcpy stpncpy strcasecmp strchr strdup \ diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index c87bd765776..dee36173896 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -993,6 +993,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_VECTOR_TYPE: case DEMANGLE_COMPONENT_CLONE: case DEMANGLE_COMPONENT_MODULE_ENTITY: + case DEMANGLE_COMPONENT_CONSTRAINTS: if (left == NULL || right == NULL) return NULL; break; @@ -1036,6 +1037,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_TEMPLATE_NON_TYPE_PARM: case DEMANGLE_COMPONENT_TEMPLATE_TEMPLATE_PARM: case DEMANGLE_COMPONENT_TEMPLATE_PACK_PARM: + case DEMANGLE_COMPONENT_FRIEND: if (left == NULL) return NULL; break; @@ -1344,6 +1346,22 @@ is_ctor_dtor_or_conversion (struct demangle_component *dc) } } +/* [ Q ] */ + +static struct demangle_component * +d_maybe_constraints (struct d_info *di, struct demangle_component *dc) +{ + if (d_peek_char (di) == 'Q') + { + d_advance (di, 1); + struct demangle_component *expr = d_expression (di); + if (expr == NULL) + return NULL; + dc = d_make_comp (di, DEMANGLE_COMPONENT_CONSTRAINTS, dc, expr); + } + return dc; +} + /* ::= <(function) name> ::= <(data) name> ::= @@ -1397,21 +1415,21 @@ d_encoding (struct d_info *di, int top_level) struct demangle_component *ftype; ftype = d_bare_function_type (di, has_return_type (dc)); - if (ftype) - { - /* If this is a non-top-level local-name, clear the - return type, so it doesn't confuse the user by - being confused with the return type of whaever - this is nested within. */ - if (!top_level && dc->type == DEMANGLE_COMPONENT_LOCAL_NAME - && ftype->type == DEMANGLE_COMPONENT_FUNCTION_TYPE) - d_left (ftype) = NULL; - - dc = d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, - dc, ftype); - } - else - dc = NULL; + if (!ftype) + return NULL; + + /* If this is a non-top-level local-name, clear the + return type, so it doesn't confuse the user by + being confused with the return type of whaever + this is nested within. */ + if (!top_level && dc->type == DEMANGLE_COMPONENT_LOCAL_NAME + && ftype->type == DEMANGLE_COMPONENT_FUNCTION_TYPE) + d_left (ftype) = NULL; + + ftype = d_maybe_constraints (di, ftype); + + dc = d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, + dc, ftype); } } } @@ -1681,6 +1699,7 @@ d_maybe_module_name (struct d_info *di, struct demangle_component **name) /* ::= [] [] ::= [] [] ::= [] [] + ::= [] F [] ::= [] [] ::= [] DC + E [] ::= L [] @@ -1692,11 +1711,18 @@ d_unqualified_name (struct d_info *di, struct demangle_component *scope, { struct demangle_component *ret; char peek; + int member_like_friend = 0; if (!d_maybe_module_name (di, &module)) return NULL; peek = d_peek_char (di); + if (peek == 'F') + { + member_like_friend = 1; + d_advance (di, 1); + peek = d_peek_char (di); + } if (IS_DIGIT (peek)) ret = d_source_name (di); else if (IS_LOWER (peek)) @@ -1773,6 +1799,8 @@ d_unqualified_name (struct d_info *di, struct demangle_component *scope, ret = d_make_comp (di, DEMANGLE_COMPONENT_MODULE_ENTITY, ret, module); if (d_peek_char (di) == 'B') ret = d_abi_tags (di, ret); + if (member_like_friend) + ret = d_make_comp (di, DEMANGLE_COMPONENT_FRIEND, ret, NULL); if (scope) ret = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, scope, ret); @@ -3012,7 +3040,7 @@ d_parmlist (struct d_info *di) struct demangle_component *type; char peek = d_peek_char (di); - if (peek == '\0' || peek == 'E' || peek == '.') + if (peek == '\0' || peek == 'E' || peek == '.' || peek == 'Q') break; if ((peek == 'R' || peek == 'O') && d_peek_next_char (di) == 'E') @@ -3248,7 +3276,7 @@ d_template_args (struct d_info *di) return d_template_args_1 (di); } -/* * E */ +/* * [Q ] E */ static struct demangle_component * d_template_args_1 (struct d_info *di) @@ -3284,13 +3312,17 @@ d_template_args_1 (struct d_info *di) return NULL; pal = &d_right (*pal); - if (d_peek_char (di) == 'E') - { - d_advance (di, 1); - break; - } + char peek = d_peek_char (di); + if (peek == 'E' || peek == 'Q') + break; } + al = d_maybe_constraints (di, al); + + if (d_peek_char (di) != 'E') + return NULL; + d_advance (di, 1); + di->last_name = hold_last_name; return al; @@ -4431,6 +4463,7 @@ d_count_templates_scopes (struct d_print_info *dpi, case DEMANGLE_COMPONENT_PACK_EXPANSION: case DEMANGLE_COMPONENT_TAGGED_NAME: case DEMANGLE_COMPONENT_CLONE: + case DEMANGLE_COMPONENT_CONSTRAINTS: recurse_left_right: /* PR 89394 - Check for too much recursion. */ if (dpi->recursion > DEMANGLE_RECURSION_LIMIT) @@ -4459,6 +4492,7 @@ d_count_templates_scopes (struct d_print_info *dpi, case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS: case DEMANGLE_COMPONENT_MODULE_ENTITY: + case DEMANGLE_COMPONENT_FRIEND: d_count_templates_scopes (dpi, d_left (dc)); break; @@ -5189,6 +5223,22 @@ d_print_comp_inner (struct d_print_info *dpi, int options, dpt.next = dpi->templates; dpi->templates = &dpt; dpt.template_decl = typed_name; + + /* Constraints are mangled as part of the template argument list, + so they wrap the _TEMPLATE_ARGLIST. But + d_lookup_template_argument expects the RHS of _TEMPLATE to be + the _ARGLIST, and constraints need to refer to these args. So + move the _CONSTRAINTS out of the _TEMPLATE and onto the type. + This will result in them being printed after the () like a + trailing requires-clause, but that seems like our best option + given that we aren't printing a template-head. */ + struct demangle_component *tnr = d_right (typed_name); + if (tnr->type == DEMANGLE_COMPONENT_CONSTRAINTS) + { + d_right (typed_name) = d_left (tnr); + d_left (tnr) = d_right (dc); + d_right (dc) = tnr; + } } d_print_comp (dpi, options, d_right (dc)); @@ -6197,6 +6247,11 @@ d_print_comp_inner (struct d_print_info *dpi, int options, d_append_char (dpi, ']'); return; + case DEMANGLE_COMPONENT_FRIEND: + d_print_comp (dpi, options, d_left (dc)); + d_append_string (dpi, "[friend]"); + return; + case DEMANGLE_COMPONENT_TEMPLATE_HEAD: { d_append_char (dpi, '<'); @@ -6231,6 +6286,12 @@ d_print_comp_inner (struct d_print_info *dpi, int options, d_append_string (dpi, "..."); return; + case DEMANGLE_COMPONENT_CONSTRAINTS: + d_print_comp (dpi, options, d_left (dc)); + d_append_string (dpi, " requires "); + d_print_comp (dpi, options, d_right (dc)); + return; + default: d_print_error (dpi); return; diff --git a/libiberty/pex-unix.c b/libiberty/pex-unix.c index 4b004f5a9cc..af98062a94c 100644 --- a/libiberty/pex-unix.c +++ b/libiberty/pex-unix.c @@ -58,6 +58,9 @@ extern int errno; #ifdef HAVE_PROCESS_H #include #endif +#ifdef HAVE_SPAWN_H +#include +#endif #ifdef vfork /* Autoconf may define this to fork for us. */ # define VFORK_STRING "fork" @@ -305,8 +308,8 @@ static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *, int, int, int, int, const char **, int *); static int pex_unix_close (struct pex_obj *, int); -static int pex_unix_wait (struct pex_obj *, pid_t, int *, struct pex_time *, - int, const char **, int *); +static pid_t pex_unix_wait (struct pex_obj *, pid_t, int *, struct pex_time *, + int, const char **, int *); static int pex_unix_pipe (struct pex_obj *, int *, int); static FILE *pex_unix_fdopenr (struct pex_obj *, int, int); static FILE *pex_unix_fdopenw (struct pex_obj *, int, int); @@ -559,6 +562,171 @@ pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, return (pid_t) -1; } +#elif defined(HAVE_POSIX_SPAWN) && defined(HAVE_POSIX_SPAWNP) +/* Implementation of pex->exec_child using posix_spawn. */ + +static pid_t +pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, + int flags, const char *executable, + char * const * argv, char * const * env, + int in, int out, int errdes, + int toclose, const char **errmsg, int *err) +{ + int ret; + pid_t pid = -1; + posix_spawnattr_t attr; + posix_spawn_file_actions_t actions; + int attr_initialized = 0, actions_initialized = 0; + + *err = 0; + + ret = posix_spawnattr_init (&attr); + if (ret) + { + *err = ret; + *errmsg = "posix_spawnattr_init"; + goto exit; + } + attr_initialized = 1; + + /* Use vfork() on glibc <=2.24. */ +#ifdef POSIX_SPAWN_USEVFORK + ret = posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK); + if (ret) + { + *err = ret; + *errmsg = "posix_spawnattr_setflags"; + goto exit; + } +#endif + + ret = posix_spawn_file_actions_init (&actions); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_init"; + goto exit; + } + actions_initialized = 1; + + if (in != STDIN_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&actions, in, STDIN_FILE_NO); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_adddup2"; + goto exit; + } + + ret = posix_spawn_file_actions_addclose (&actions, in); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_addclose"; + goto exit; + } + } + + if (out != STDOUT_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&actions, out, STDOUT_FILE_NO); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_adddup2"; + goto exit; + } + + ret = posix_spawn_file_actions_addclose (&actions, out); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_addclose"; + goto exit; + } + } + + if (errdes != STDERR_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&actions, errdes, STDERR_FILE_NO); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_adddup2"; + goto exit; + } + + ret = posix_spawn_file_actions_addclose (&actions, errdes); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_addclose"; + goto exit; + } + } + + if (toclose >= 0) + { + ret = posix_spawn_file_actions_addclose (&actions, toclose); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_addclose"; + goto exit; + } + } + + if ((flags & PEX_STDERR_TO_STDOUT) != 0) + { + ret = posix_spawn_file_actions_adddup2 (&actions, STDOUT_FILE_NO, STDERR_FILE_NO); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_adddup2"; + goto exit; + } + } + + if ((flags & PEX_SEARCH) != 0) + { + ret = posix_spawnp (&pid, executable, &actions, &attr, argv, env ? env : environ); + if (ret) + { + *err = ret; + *errmsg = "posix_spawnp"; + goto exit; + } + } + else + { + ret = posix_spawn (&pid, executable, &actions, &attr, argv, env ? env : environ); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn"; + goto exit; + } + } + +exit: + if (actions_initialized) + posix_spawn_file_actions_destroy (&actions); + if (attr_initialized) + posix_spawnattr_destroy (&attr); + + if (!*err && in != STDIN_FILE_NO) + if (close (in)) + *errmsg = "close", *err = errno, pid = -1; + if (!*err && out != STDOUT_FILE_NO) + if (close (out)) + *errmsg = "close", *err = errno, pid = -1; + if (!*err && errdes != STDERR_FILE_NO) + if (close (errdes)) + *errmsg = "close", *err = errno, pid = -1; + + return pid; +} #else /* Implementation of pex->exec_child using standard vfork + exec. */ @@ -766,7 +934,7 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, /* Wait for a child process to complete. */ -static int +static pid_t pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time, int done, const char **errmsg, int *err) diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 0acd2d635db..0997e96ea43 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -1689,3 +1689,14 @@ X::operator Z()::y _ZZN1XIfEcv1ZIT_EIiEEvE1y X::operator Z()::y + +_ZN1SILi1EEF3barIiEEiR4Base +int S<1>::bar[friend](Base&) + +# requires on template-head +_Z1fIiQ1CIT_EEvv +void f() requires C + +# requires after () +_Z1fIiEvvQ1CIT_E +void f() requires C