summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2022-10-28 14:40:25 +0000
committerJoseph Myers <joseph@codesourcery.com>2022-10-28 14:40:25 +0000
commit4fe34cdcc80ac225b80670eabc38ac5e31ce8a5a (patch)
treedb3484b3bd407d4efbe918ca7303aa09d68d818a /gcc/config
parent988dd22ec6665117e8587389ac85389f1c321c45 (diff)
downloadgcc-4fe34cdcc80ac225b80670eabc38ac5e31ce8a5a.tar.gz
c: tree: target: C2x (...) function prototypes and va_start relaxation
C2x allows function prototypes to be given as (...), a prototype meaning a variable-argument function with no named arguments. To allow such functions to access their arguments, requirements for va_start calls are relaxed so it ignores all but its first argument (i.e. subsequent arguments, if any, can be arbitrary pp-token sequences). Implement this feature accordingly. The va_start relaxation in <stdarg.h> is itself easy: __builtin_va_start already supports a second argument of 0 instead of a parameter name, and calls get converted internally to the form using 0 for that argument, so <stdarg.h> just needs changing to use a variadic macro that passes 0 as the second argument of __builtin_va_start. (This is done only in C2x mode, on the expectation that users of older standard would expect unsupported uses of va_start to be diagnosed.) For the (...) functions, it's necessary to distinguish these from unprototyped functions, whereas previously C++ (...) functions and unprototyped functions both used NULL TYPE_ARG_TYPES. A flag is added to tree_type_common to mark the (...) functions; as discussed on gcc@, doing things this way is likely to be safer for unchanged code in GCC than adding a different form of representation in TYPE_ARG_TYPES, or adding a flag that instead signals that the function is unprototyped. There was previously an option -fallow-parameterless-variadic-functions to enable support for (...) prototypes. The support was incomplete - it treated the functions as unprototyped, and only parsed some declarations, not e.g. "int g (int (...));". This option is changed into a no-op ignored option; (...) is always accepted syntactically, with a pedwarn_c11 call to given required diagnostics when appropriate. The peculiarity of a parameter list with __attribute__ followed by '...' being accepted with that option is removed. Interfaces in tree.cc that create function types are adjusted to set this flag as appropriate. It is of course possible that some existing users of the functions to create variable-argument functions actually wanted unprototyped functions in the no-named-argument case, rather than functions with a (...) prototype; some such cases in c-common.cc (for built-in functions and implicit function declarations) turn out to need updating for that reason. I didn't do anything to change how the C++ front end creates (...) function types. It's very likely there are unchanged places in the compiler that in fact turn out to need changes to work properly with (...) function prototypes. Target setup_incoming_varargs hooks, where they used the information passed about the last named argument, needed updating to avoid using that information in the (...) case. Note that apart from the x86 changes, I haven't done any testing of those target changes beyond building cc1 to check for syntax errors. It's possible further target-specific fixes will be needed; target maintainers should watch out for failures of c2x-stdarg-4.c or c2x-stdarg-split-1a.c, the execution tests, which would indicate that this feature is not working correctly. Those tests also verify the case where there are named arguments but the last named argument has a declaration that results in undefined behavior in previous C standard versions, such as a type changed by the default argument promotions. Bootstrapped with no regressions for x86_64-pc-linux-gnu. gcc/ * config/aarch64/aarch64.cc (aarch64_setup_incoming_varargs): Check TYPE_NO_NAMED_ARGS_STDARG_P. * config/alpha/alpha.cc (alpha_setup_incoming_varargs): Likewise. * config/arc/arc.cc (arc_setup_incoming_varargs): Likewise. * config/arm/arm.cc (arm_setup_incoming_varargs): Likewise. * config/csky/csky.cc (csky_setup_incoming_varargs): Likewise. * config/epiphany/epiphany.cc (epiphany_setup_incoming_varargs): Likewise. * config/fr30/fr30.cc (fr30_setup_incoming_varargs): Likewise. * config/frv/frv.cc (frv_setup_incoming_varargs): Likewise. * config/ft32/ft32.cc (ft32_setup_incoming_varargs): Likewise. * config/i386/i386.cc (ix86_setup_incoming_varargs): Likewise. * config/ia64/ia64.cc (ia64_setup_incoming_varargs): Likewise. * config/loongarch/loongarch.cc (loongarch_setup_incoming_varargs): Likewise. * config/m32r/m32r.cc (m32r_setup_incoming_varargs): Likewise. * config/mcore/mcore.cc (mcore_setup_incoming_varargs): Likewise. * config/mips/mips.cc (mips_setup_incoming_varargs): Likewise. * config/mmix/mmix.cc (mmix_setup_incoming_varargs): Likewise. * config/nds32/nds32.cc (nds32_setup_incoming_varargs): Likewise. * config/nios2/nios2.cc (nios2_setup_incoming_varargs): Likewise. * config/riscv/riscv.cc (riscv_setup_incoming_varargs): Likewise. * config/rs6000/rs6000-call.cc (setup_incoming_varargs): Likewise. * config/sh/sh.cc (sh_setup_incoming_varargs): Likewise. * config/visium/visium.cc (visium_setup_incoming_varargs): Likewise. * config/vms/vms-c.cc (vms_c_common_override_options): Do not set flag_allow_parameterless_variadic_functions. * doc/invoke.texi (-fallow-parameterless-variadic-functions): Do not document option. * function.cc (assign_parms): Call assign_parms_setup_varargs for TYPE_NO_NAMED_ARGS_STDARG_P case. * ginclude/stdarg.h [__STDC_VERSION__ > 201710L] (va_start): Make variadic macro. Pass second argument of 0 to __builtin_va_start. * target.def (setup_incoming_varargs): Update documentation. * doc/tm.texi: Regenerate. * tree-core.h (struct tree_type_common): Add no_named_args_stdarg_p. * tree-streamer-in.cc (unpack_ts_type_common_value_fields): Unpack TYPE_NO_NAMED_ARGS_STDARG_P. * tree-streamer-out.cc (pack_ts_type_common_value_fields): Pack TYPE_NO_NAMED_ARGS_STDARG_P. * tree.cc (type_cache_hasher::equal): Compare TYPE_NO_NAMED_ARGS_STDARG_P. (build_function_type): Add argument no_named_args_stdarg_p. (build_function_type_list_1, build_function_type_array_1) (reconstruct_complex_type): Update calls to build_function_type. (stdarg_p, prototype_p): Return true for (...) functions. (gimple_canonical_types_compatible_p): Compare TYPE_NO_NAMED_ARGS_STDARG_P. * tree.h (TYPE_NO_NAMED_ARGS_STDARG_P): New. (build_function_type): Update prototype. gcc/c-family/ * c-common.cc (def_fn_type): Call build_function_type for zero-argument variable-argument function. (c_common_nodes_and_builtins): Build default_function_type with build_function_type. * c.opt (fallow-parameterless-variadic-functions): Mark as ignored option. gcc/c/ * c-decl.cc (grokdeclarator): Pass arg_info->no_named_args_stdarg_p to build_function_type. (grokparms): Check arg_info->no_named_args_stdarg_p before converting () to (void). (build_arg_info): Initialize no_named_args_stdarg_p. (get_parm_info): Set no_named_args_stdarg_p. (start_function): Pass TYPE_NO_NAMED_ARGS_STDARG_P to build_function_type. (store_parm_decls): Count (...) functions as prototyped. * c-parser.cc (c_parser_direct_declarator): Allow '...' after open parenthesis to start parameter list. (c_parser_parms_list_declarator): Always allow '...' with no arguments, call pedwarn_c11 and set no_named_args_stdarg_p. * c-tree.h (struct c_arg_info): Add field no_named_args_stdarg_p. * c-typeck.cc (composite_type): Handle TYPE_NO_NAMED_ARGS_STDARG_P. (function_types_compatible_p): Compare TYPE_NO_NAMED_ARGS_STDARG_P. gcc/fortran/ * trans-types.cc (gfc_get_function_type): Do not use build_varargs_function_type_vec for unprototyped function. gcc/lto/ * lto-common.cc (compare_tree_sccs_1): Compare TYPE_NO_NAMED_ARGS_STDARG_P. gcc/objc/ * objc-next-runtime-abi-01.cc (build_next_objc_exception_stuff): Use build_function_type to build type of objc_setjmp_decl. gcc/testsuite/ * gcc.dg/c11-stdarg-1.c, gcc.dg/c11-stdarg-2.c, gcc.dg/c11-stdarg-3.c, gcc.dg/c2x-stdarg-1.c, gcc.dg/c2x-stdarg-2.c, gcc.dg/c2x-stdarg-3.c, gcc.dg/c2x-stdarg-4.c, gcc.dg/gnu2x-stdarg-1.c, gcc.dg/torture/c2x-stdarg-split-1a.c, gcc.dg/torture/c2x-stdarg-split-1b.c: New tests. * gcc.dg/Wold-style-definition-2.c, gcc.dg/format/sentinel-1.c: Update expected diagnostics. * gcc.dg/c2x-nullptr-1.c (test5): Cast unused parameter to (void). * gcc.dg/diagnostic-token-ranges.c: Use -pedantic. Expect warning in place of error.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/aarch64/aarch64.cc3
-rw-r--r--gcc/config/alpha/alpha.cc5
-rw-r--r--gcc/config/arc/arc.cc3
-rw-r--r--gcc/config/arm/arm.cc3
-rw-r--r--gcc/config/csky/csky.cc3
-rw-r--r--gcc/config/epiphany/epiphany.cc8
-rw-r--r--gcc/config/fr30/fr30.cc23
-rw-r--r--gcc/config/frv/frv.cc3
-rw-r--r--gcc/config/ft32/ft32.cc6
-rw-r--r--gcc/config/i386/i386.cc3
-rw-r--r--gcc/config/ia64/ia64.cc5
-rw-r--r--gcc/config/loongarch/loongarch.cc3
-rw-r--r--gcc/config/m32r/m32r.cc12
-rw-r--r--gcc/config/mcore/mcore.cc5
-rw-r--r--gcc/config/mips/mips.cc3
-rw-r--r--gcc/config/mmix/mmix.cc3
-rw-r--r--gcc/config/nds32/nds32.cc9
-rw-r--r--gcc/config/nios2/nios2.cc3
-rw-r--r--gcc/config/riscv/riscv.cc3
-rw-r--r--gcc/config/rs6000/rs6000-call.cc7
-rw-r--r--gcc/config/sh/sh.cc9
-rw-r--r--gcc/config/visium/visium.cc3
-rw-r--r--gcc/config/vms/vms-c.cc3
23 files changed, 79 insertions, 49 deletions
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 0458c65db81..d1f979ebcf8 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -19891,7 +19891,8 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v,
argument. Advance a local copy of CUM past the last "real" named
argument, to find out how many registers are left over. */
local_cum = *cum;
- aarch64_function_arg_advance (pack_cumulative_args(&local_cum), arg);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ aarch64_function_arg_advance (pack_cumulative_args(&local_cum), arg);
/* Found out how many registers we need to save.
Honor tree-stdvar analysis results. */
diff --git a/gcc/config/alpha/alpha.cc b/gcc/config/alpha/alpha.cc
index 66c17149d4d..333f2c602c4 100644
--- a/gcc/config/alpha/alpha.cc
+++ b/gcc/config/alpha/alpha.cc
@@ -6084,8 +6084,9 @@ alpha_setup_incoming_varargs (cumulative_args_t pcum,
{
CUMULATIVE_ARGS cum = *get_cumulative_args (pcum);
- /* Skip the current argument. */
- targetm.calls.function_arg_advance (pack_cumulative_args (&cum), arg);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ /* Skip the current argument. */
+ targetm.calls.function_arg_advance (pack_cumulative_args (&cum), arg);
#if TARGET_ABI_OPEN_VMS
/* For VMS, we allocate space for all 6 arg registers plus a count.
diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc
index e6f52d87714..604a116e966 100644
--- a/gcc/config/arc/arc.cc
+++ b/gcc/config/arc/arc.cc
@@ -2450,7 +2450,8 @@ arc_setup_incoming_varargs (cumulative_args_t args_so_far,
/* We must treat `__builtin_va_alist' as an anonymous arg. */
next_cum = *get_cumulative_args (args_so_far);
- arc_function_arg_advance (pack_cumulative_args (&next_cum), arg);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ arc_function_arg_advance (pack_cumulative_args (&next_cum), arg);
first_anon_arg = next_cum;
if (FUNCTION_ARG_REGNO_P (first_anon_arg))
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index ee8f1babf8a..2eb4d51e4a3 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -29143,7 +29143,8 @@ arm_setup_incoming_varargs (cumulative_args_t pcum_v,
if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
{
nregs = pcum->aapcs_ncrn;
- if (nregs & 1)
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
+ && (nregs & 1))
{
int res = arm_needs_doubleword_align (arg.mode, arg.type);
if (res < 0 && warn_psabi)
diff --git a/gcc/config/csky/csky.cc b/gcc/config/csky/csky.cc
index f7b2bf8e7c1..537eee6ab88 100644
--- a/gcc/config/csky/csky.cc
+++ b/gcc/config/csky/csky.cc
@@ -2086,7 +2086,8 @@ csky_setup_incoming_varargs (cumulative_args_t pcum_v,
cfun->machine->uses_anonymous_args = 1;
local_cum = *pcum;
- csky_function_arg_advance (local_cum_v, arg);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ csky_function_arg_advance (local_cum_v, arg);
regs_to_push = CSKY_NPARM_REGS - local_cum.reg;
if (regs_to_push)
*pretend_size = regs_to_push * UNITS_PER_WORD;
diff --git a/gcc/config/epiphany/epiphany.cc b/gcc/config/epiphany/epiphany.cc
index f8c04934085..c4e3ceaeb2a 100644
--- a/gcc/config/epiphany/epiphany.cc
+++ b/gcc/config/epiphany/epiphany.cc
@@ -727,11 +727,13 @@ epiphany_setup_incoming_varargs (cumulative_args_t cum,
machine_function_t *mf = MACHINE_FUNCTION (cfun);
/* All BLKmode values are passed by reference. */
- gcc_assert (arg.mode != BLKmode);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ gcc_assert (arg.mode != BLKmode);
next_cum = *get_cumulative_args (cum);
- next_cum = (ROUND_ADVANCE_CUM (next_cum, arg.mode, arg.type)
- + ROUND_ADVANCE_ARG (arg.mode, arg.type));
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ next_cum = (ROUND_ADVANCE_CUM (next_cum, arg.mode, arg.type)
+ + ROUND_ADVANCE_ARG (arg.mode, arg.type));
first_anon_arg = next_cum;
if (first_anon_arg < MAX_EPIPHANY_PARM_REGS && !no_rtl)
diff --git a/gcc/config/fr30/fr30.cc b/gcc/config/fr30/fr30.cc
index c9b061d218b..334bb44e37f 100644
--- a/gcc/config/fr30/fr30.cc
+++ b/gcc/config/fr30/fr30.cc
@@ -471,16 +471,19 @@ fr30_setup_incoming_varargs (cumulative_args_t arg_regs_used_so_far_v,
= get_cumulative_args (arg_regs_used_so_far_v);
int size;
- /* All BLKmode values are passed by reference. */
- gcc_assert (arg.mode != BLKmode);
-
- /* ??? This run-time test as well as the code inside the if
- statement is probably unnecessary. */
- if (targetm.calls.strict_argument_naming (arg_regs_used_so_far_v))
- /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named
- arg must not be treated as an anonymous arg. */
- /* ??? This is a pointer increment, which makes no sense. */
- arg_regs_used_so_far += fr30_num_arg_regs (arg);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ {
+ /* All BLKmode values are passed by reference. */
+ gcc_assert (arg.mode != BLKmode);
+
+ /* ??? This run-time test as well as the code inside the if
+ statement is probably unnecessary. */
+ if (targetm.calls.strict_argument_naming (arg_regs_used_so_far_v))
+ /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named
+ arg must not be treated as an anonymous arg. */
+ /* ??? This is a pointer increment, which makes no sense. */
+ arg_regs_used_so_far += fr30_num_arg_regs (arg);
+ }
size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far);
diff --git a/gcc/config/frv/frv.cc b/gcc/config/frv/frv.cc
index 6f1904b358c..5cdb0bfe6e9 100644
--- a/gcc/config/frv/frv.cc
+++ b/gcc/config/frv/frv.cc
@@ -2104,7 +2104,8 @@ frv_setup_incoming_varargs (cumulative_args_t cum_v,
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
- if (TARGET_DEBUG_ARG)
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
+ && TARGET_DEBUG_ARG)
fprintf (stderr,
"setup_vararg: words = %2d, mode = %4s, pretend_size = %d, second_time = %d\n",
*cum, GET_MODE_NAME (arg.mode), *pretend_size, second_time);
diff --git a/gcc/config/ft32/ft32.cc b/gcc/config/ft32/ft32.cc
index ed2d1229d61..d6b73d48686 100644
--- a/gcc/config/ft32/ft32.cc
+++ b/gcc/config/ft32/ft32.cc
@@ -634,8 +634,10 @@ ft32_setup_incoming_varargs (cumulative_args_t cum_v,
int *pretend_size, int no_rtl ATTRIBUTE_UNUSED)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
- int named_size =
- GET_MODE_SIZE (SImode) * (*cum - FT32_R0) + GET_MODE_SIZE (arg.mode);
+ int named_size = 0;
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ named_size =
+ GET_MODE_SIZE (SImode) * (*cum - FT32_R0) + GET_MODE_SIZE (arg.mode);
if (named_size < 24)
*pretend_size = 24 - named_size;
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index aeea26ef4be..e775ba4ad6c 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -4559,7 +4559,8 @@ ix86_setup_incoming_varargs (cumulative_args_t cum_v,
/* For varargs, we do not want to skip the dummy va_dcl argument.
For stdargs, we do want to skip the last named argument. */
next_cum = *cum;
- if (stdarg_p (fntype))
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
+ && stdarg_p (fntype))
ix86_function_arg_advance (pack_cumulative_args (&next_cum), arg);
if (cum->call_abi == MS_ABI)
diff --git a/gcc/config/ia64/ia64.cc b/gcc/config/ia64/ia64.cc
index 995ff906940..6df1ce736bc 100644
--- a/gcc/config/ia64/ia64.cc
+++ b/gcc/config/ia64/ia64.cc
@@ -4596,8 +4596,9 @@ ia64_setup_incoming_varargs (cumulative_args_t cum,
{
CUMULATIVE_ARGS next_cum = *get_cumulative_args (cum);
- /* Skip the current argument. */
- ia64_function_arg_advance (pack_cumulative_args (&next_cum), arg);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ /* Skip the current argument. */
+ ia64_function_arg_advance (pack_cumulative_args (&next_cum), arg);
if (next_cum.words < MAX_ARGUMENT_SLOTS)
{
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index e9ba3374e35..f54c233f90c 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -756,7 +756,8 @@ loongarch_setup_incoming_varargs (cumulative_args_t cum,
argument. Advance a local copy of CUM past the last "real" named
argument, to find out how many registers are left over. */
local_cum = *get_cumulative_args (cum);
- loongarch_function_arg_advance (pack_cumulative_args (&local_cum), arg);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ loongarch_function_arg_advance (pack_cumulative_args (&local_cum), arg);
/* Found out how many registers we need to save. */
gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
diff --git a/gcc/config/m32r/m32r.cc b/gcc/config/m32r/m32r.cc
index bca768172b7..e3489fb4dc0 100644
--- a/gcc/config/m32r/m32r.cc
+++ b/gcc/config/m32r/m32r.cc
@@ -1287,11 +1287,15 @@ m32r_setup_incoming_varargs (cumulative_args_t cum,
return;
/* All BLKmode values are passed by reference. */
- gcc_assert (arg.mode != BLKmode);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ gcc_assert (arg.mode != BLKmode);
- first_anon_arg = (ROUND_ADVANCE_CUM (*get_cumulative_args (cum),
- arg.mode, arg.type)
- + ROUND_ADVANCE_ARG (arg.mode, arg.type));
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ first_anon_arg = (ROUND_ADVANCE_CUM (*get_cumulative_args (cum),
+ arg.mode, arg.type)
+ + ROUND_ADVANCE_ARG (arg.mode, arg.type));
+ else
+ first_anon_arg = *get_cumulative_args (cum);
if (first_anon_arg < M32R_MAX_PARM_REGS)
{
diff --git a/gcc/config/mcore/mcore.cc b/gcc/config/mcore/mcore.cc
index 28e707496d1..605d63b6a70 100644
--- a/gcc/config/mcore/mcore.cc
+++ b/gcc/config/mcore/mcore.cc
@@ -1953,8 +1953,9 @@ mcore_setup_incoming_varargs (cumulative_args_t args_so_far_v,
/* We need to know how many argument registers are used before
the varargs start, so that we can push the remaining argument
registers during the prologue. */
- number_of_regs_before_varargs
- = *args_so_far + mcore_num_arg_regs (arg.mode, arg.type);
+ number_of_regs_before_varargs = *args_so_far;
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ number_of_regs_before_varargs += mcore_num_arg_regs (arg.mode, arg.type);
/* There is a bug somewhere in the arg handling code.
Until I can find it this workaround always pushes the
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 699ea6cc128..0ac0248fb9e 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -6683,7 +6683,8 @@ mips_setup_incoming_varargs (cumulative_args_t cum,
argument. Advance a local copy of CUM past the last "real" named
argument, to find out how many registers are left over. */
local_cum = *get_cumulative_args (cum);
- mips_function_arg_advance (pack_cumulative_args (&local_cum), arg);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ mips_function_arg_advance (pack_cumulative_args (&local_cum), arg);
/* Found out how many registers we need to save. */
gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
diff --git a/gcc/config/mmix/mmix.cc b/gcc/config/mmix/mmix.cc
index ffdd8c71cc1..1ac7b883ac5 100644
--- a/gcc/config/mmix/mmix.cc
+++ b/gcc/config/mmix/mmix.cc
@@ -999,7 +999,8 @@ mmix_setup_incoming_varargs (cumulative_args_t args_so_farp_v,
/* We assume that one argument takes up one register here. That should
be true until we start messing with multi-reg parameters. */
- if ((7 + (MMIX_FUNCTION_ARG_SIZE (arg.mode, arg.type))) / 8 != 1)
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
+ && (7 + (MMIX_FUNCTION_ARG_SIZE (arg.mode, arg.type))) / 8 != 1)
internal_error ("MMIX Internal: Last named vararg would not fit in a register");
}
diff --git a/gcc/config/nds32/nds32.cc b/gcc/config/nds32/nds32.cc
index 67a612130fe..639baef6c17 100644
--- a/gcc/config/nds32/nds32.cc
+++ b/gcc/config/nds32/nds32.cc
@@ -2377,9 +2377,12 @@ nds32_setup_incoming_varargs (cumulative_args_t ca,
for varargs. */
total_args_regs
= NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM;
- num_of_used_regs
- = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, arg.mode, arg.type)
- + NDS32_NEED_N_REGS_FOR_ARG (arg.mode, arg.type);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ num_of_used_regs
+ = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, arg.mode, arg.type)
+ + NDS32_NEED_N_REGS_FOR_ARG (arg.mode, arg.type);
+ else
+ num_of_used_regs = cum->gpr_offset + NDS32_GPR_ARG_FIRST_REGNUM;
remaining_reg_count = total_args_regs - num_of_used_regs;
*pretend_args_size = remaining_reg_count * UNITS_PER_WORD;
diff --git a/gcc/config/nios2/nios2.cc b/gcc/config/nios2/nios2.cc
index 1a33c88f19f..6a894ec345e 100644
--- a/gcc/config/nios2/nios2.cc
+++ b/gcc/config/nios2/nios2.cc
@@ -3524,7 +3524,8 @@ nios2_setup_incoming_varargs (cumulative_args_t cum_v,
cfun->machine->uses_anonymous_args = 1;
local_cum = *cum;
- nios2_function_arg_advance (local_cum_v, arg);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ nios2_function_arg_advance (local_cum_v, arg);
regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 77bc65b0881..32f9ef9ade9 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3730,7 +3730,8 @@ riscv_setup_incoming_varargs (cumulative_args_t cum,
argument. Advance a local copy of CUM past the last "real" named
argument, to find out how many registers are left over. */
local_cum = *get_cumulative_args (cum);
- riscv_function_arg_advance (pack_cumulative_args (&local_cum), arg);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ riscv_function_arg_advance (pack_cumulative_args (&local_cum), arg);
/* Found out how many registers we need to save. */
gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
diff --git a/gcc/config/rs6000/rs6000-call.cc b/gcc/config/rs6000/rs6000-call.cc
index ac3cb7e3d36..6da4de67137 100644
--- a/gcc/config/rs6000/rs6000-call.cc
+++ b/gcc/config/rs6000/rs6000-call.cc
@@ -2253,7 +2253,9 @@ setup_incoming_varargs (cumulative_args_t cum,
/* Skip the last named argument. */
next_cum = *get_cumulative_args (cum);
- rs6000_function_arg_advance_1 (&next_cum, arg.mode, arg.type, arg.named, 0);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ rs6000_function_arg_advance_1 (&next_cum, arg.mode, arg.type, arg.named,
+ 0);
if (DEFAULT_ABI == ABI_V4)
{
@@ -2327,7 +2329,8 @@ setup_incoming_varargs (cumulative_args_t cum,
first_reg_offset = next_cum.words;
save_area = crtl->args.internal_arg_pointer;
- if (targetm.calls.must_pass_in_stack (arg))
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
+ && targetm.calls.must_pass_in_stack (arg))
first_reg_offset += rs6000_arg_size (TYPE_MODE (arg.type), arg.type);
}
diff --git a/gcc/config/sh/sh.cc b/gcc/config/sh/sh.cc
index 9bee618b639..1aec70a23d8 100644
--- a/gcc/config/sh/sh.cc
+++ b/gcc/config/sh/sh.cc
@@ -8183,11 +8183,12 @@ sh_setup_incoming_varargs (cumulative_args_t ca,
gcc_assert (cfun->stdarg);
if (TARGET_VARARGS_PRETEND_ARGS (current_function_decl))
{
- int named_parm_regs, anon_parm_regs;
+ int named_parm_regs = 0, anon_parm_regs;
- named_parm_regs = (sh_round_reg (*get_cumulative_args (ca), arg.mode)
- + CEIL (arg.promoted_size_in_bytes (),
- UNITS_PER_WORD));
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ named_parm_regs = (sh_round_reg (*get_cumulative_args (ca), arg.mode)
+ + CEIL (arg.promoted_size_in_bytes (),
+ UNITS_PER_WORD));
anon_parm_regs = NPARM_REGS (SImode) - named_parm_regs;
if (anon_parm_regs > 0)
*pretend_arg_size = anon_parm_regs * 4;
diff --git a/gcc/config/visium/visium.cc b/gcc/config/visium/visium.cc
index 03c1a33e1b9..e7d15960fc7 100644
--- a/gcc/config/visium/visium.cc
+++ b/gcc/config/visium/visium.cc
@@ -1481,7 +1481,8 @@ visium_setup_incoming_varargs (cumulative_args_t pcum_v,
/* The caller has advanced ARGS_SO_FAR up to, but not beyond, the last named
argument. Advance a local copy of ARGS_SO_FAR past the last "real" named
argument, to find out how many registers are left over. */
- TARGET_FUNCTION_ARG_ADVANCE (local_args_so_far, arg);
+ if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
+ TARGET_FUNCTION_ARG_ADVANCE (local_args_so_far, arg);
/* Find how many registers we need to save. */
locargs = get_cumulative_args (local_args_so_far);
diff --git a/gcc/config/vms/vms-c.cc b/gcc/config/vms/vms-c.cc
index 2f74fb574cd..ccf6d5fe3b6 100644
--- a/gcc/config/vms/vms-c.cc
+++ b/gcc/config/vms/vms-c.cc
@@ -455,9 +455,6 @@ vms_c_register_includes (const char *sysroot,
void
vms_c_common_override_options (void)
{
- /* Allow variadic functions without parameters (as declared in starlet). */
- flag_allow_parameterless_variadic_functions = TRUE;
-
/* Initialize c_default_pointer_mode. */
switch (flag_vms_pointer_size)
{