c++, v3: Implement C++26 P3176R1 - The Oxford variadic comma

Message ID Z0nHwYY2E0wuW1tM@tucnak
State New
Headers
Series c++, v3: Implement C++26 P3176R1 - The Oxford variadic comma |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Jakub Jelinek Nov. 29, 2024, 1:55 p.m. UTC
  On Fri, Nov 29, 2024 at 08:36:21AM -0500, Jason Merrill wrote:
> > This should be either "omission of ',' before" or "omitting ',' before"
> > 
> > But not "omitting of" :-)
> 
> Agreed.

Picked omission of.

> I also might say "varargs" instead of "variadic", since the latter could
> also refer to variadic templates?

So like this (just in the diagnostic message and description (both docs and
option help)?
Or do you want varargs also in the option name, and perhaps names of the new
testcases, too?

2024-11-29  Jakub Jelinek  <jakub@redhat.com>

gcc/c-family/
	* c.opt: Implement C++26 P3176R1 - The Oxford variadic comma.
	(Wdeprecated-variadic-comma-omission): New option.
	* c.opt.urls: Regenerate.
	* c-opts.cc (c_common_post_options): Default to
	-Wdeprecated-variadic-comma-omission for C++26 or -Wpedantic.
gcc/cp/
	* parser.cc (cp_parser_parameter_declaration_clause): Emit
	-Wdeprecated-variadic-comma-omission warnings.
gcc/
	* doc/invoke.texi (-Wdeprecated-variadic-comma-omission): Document.
gcc/testsuite/
	* g++.dg/cpp26/variadic-comma1.C: New test.
	* g++.dg/cpp26/variadic-comma2.C: New test.
	* g++.dg/cpp26/variadic-comma3.C: New test.
	* g++.dg/cpp26/variadic-comma4.C: New test.
	* g++.dg/cpp26/variadic-comma5.C: New test.
	* g++.dg/cpp1z/fold10.C: Expect a warning for C++26.
	* g++.dg/ext/attrib33.C: Likewise.
	* g++.dg/cpp1y/lambda-generic-variadic19.C: Likewise.
	* g++.dg/cpp2a/lambda-generic10.C: Likewise.
	* g++.dg/cpp0x/lambda/lambda-const3.C: Likewise.
	* g++.dg/cpp0x/variadic164.C: Likewise.
	* g++.dg/cpp0x/variadic17.C: Likewise.
	* g++.dg/cpp0x/udlit-args-neg.C: Likewise.
	* g++.dg/cpp0x/variadic28.C: Likewise.
	* g++.dg/cpp0x/gen-attrs-33.C: Likewise.
	* g++.dg/cpp23/explicit-obj-diagnostics3.C: Likewise.
	* g++.old-deja/g++.law/operators15.C: Likewise.
	* g++.old-deja/g++.mike/p811.C: Likewise.
	* g++.old-deja/g++.mike/p12306.C (printf): Add , before ... .
	* g++.dg/analyzer/fd-bind-pr107783.C (bind): Likewise.
	* g++.dg/cpp0x/vt-65790.C (printf): Likewise.
libstdc++-v3/
	* include/std/functional (_Bind_check_arity): Add , before ... .
	* include/bits/refwrap.h (_Mem_fn_traits, _Weak_result_type_impl):
	Likewise.
	* include/tr1/type_traits (is_function): Likewise.



	Jakub
  

Comments

Jason Merrill Nov. 29, 2024, 2:27 p.m. UTC | #1
On 11/29/24 8:55 AM, Jakub Jelinek wrote:
> On Fri, Nov 29, 2024 at 08:36:21AM -0500, Jason Merrill wrote:
>>> This should be either "omission of ',' before" or "omitting ',' before"
>>>
>>> But not "omitting of" :-)
>>
>> Agreed.
> 
> Picked omission of.
> 
>> I also might say "varargs" instead of "variadic", since the latter could
>> also refer to variadic templates?
> 
> So like this (just in the diagnostic message and description (both docs and
> option help)?

OK.

> Or do you want varargs also in the option name, and perhaps names of the new
> testcases, too?
> 
> 2024-11-29  Jakub Jelinek  <jakub@redhat.com>
> 
> gcc/c-family/
> 	* c.opt: Implement C++26 P3176R1 - The Oxford variadic comma.
> 	(Wdeprecated-variadic-comma-omission): New option.
> 	* c.opt.urls: Regenerate.
> 	* c-opts.cc (c_common_post_options): Default to
> 	-Wdeprecated-variadic-comma-omission for C++26 or -Wpedantic.
> gcc/cp/
> 	* parser.cc (cp_parser_parameter_declaration_clause): Emit
> 	-Wdeprecated-variadic-comma-omission warnings.
> gcc/
> 	* doc/invoke.texi (-Wdeprecated-variadic-comma-omission): Document.
> gcc/testsuite/
> 	* g++.dg/cpp26/variadic-comma1.C: New test.
> 	* g++.dg/cpp26/variadic-comma2.C: New test.
> 	* g++.dg/cpp26/variadic-comma3.C: New test.
> 	* g++.dg/cpp26/variadic-comma4.C: New test.
> 	* g++.dg/cpp26/variadic-comma5.C: New test.
> 	* g++.dg/cpp1z/fold10.C: Expect a warning for C++26.
> 	* g++.dg/ext/attrib33.C: Likewise.
> 	* g++.dg/cpp1y/lambda-generic-variadic19.C: Likewise.
> 	* g++.dg/cpp2a/lambda-generic10.C: Likewise.
> 	* g++.dg/cpp0x/lambda/lambda-const3.C: Likewise.
> 	* g++.dg/cpp0x/variadic164.C: Likewise.
> 	* g++.dg/cpp0x/variadic17.C: Likewise.
> 	* g++.dg/cpp0x/udlit-args-neg.C: Likewise.
> 	* g++.dg/cpp0x/variadic28.C: Likewise.
> 	* g++.dg/cpp0x/gen-attrs-33.C: Likewise.
> 	* g++.dg/cpp23/explicit-obj-diagnostics3.C: Likewise.
> 	* g++.old-deja/g++.law/operators15.C: Likewise.
> 	* g++.old-deja/g++.mike/p811.C: Likewise.
> 	* g++.old-deja/g++.mike/p12306.C (printf): Add , before ... .
> 	* g++.dg/analyzer/fd-bind-pr107783.C (bind): Likewise.
> 	* g++.dg/cpp0x/vt-65790.C (printf): Likewise.
> libstdc++-v3/
> 	* include/std/functional (_Bind_check_arity): Add , before ... .
> 	* include/bits/refwrap.h (_Mem_fn_traits, _Weak_result_type_impl):
> 	Likewise.
> 	* include/tr1/type_traits (is_function): Likewise.
> 
> --- gcc/c-family/c.opt.jj	2024-11-22 19:52:19.477579338 +0100
> +++ gcc/c-family/c.opt	2024-11-25 16:22:11.325028058 +0100
> @@ -672,6 +672,10 @@ Wdeprecated-non-prototype
>   C ObjC Var(warn_deprecated_non_prototype) Init(-1) Warning
>   Warn about calls with arguments to functions declared without parameters.
>   
> +Wdeprecated-variadic-comma-omission
> +C++ ObjC++ Var(warn_deprecated_variadic_comma_omission) Warning
> +Warn about deprecated omission of comma before ... in varargs function declaration.
> +
>   Wdesignated-init
>   C ObjC Var(warn_designated_init) Init(1) Warning
>   Warn about positional initialization of structs requiring designated initializers.
> --- gcc/c-family/c.opt.urls.jj	2024-11-18 21:59:35.872150269 +0100
> +++ gcc/c-family/c.opt.urls	2024-11-25 17:38:25.396693802 +0100
> @@ -310,6 +310,9 @@ UrlSuffix(gcc/C_002b_002b-Dialect-Option
>   Wdeprecated-non-prototype
>   UrlSuffix(gcc/Warning-Options.html#index-Wdeprecated-non-prototype)
>   
> +Wdeprecated-variadic-comma-omission
> +UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wdeprecated-variadic-comma-omission)
> +
>   Wdesignated-init
>   UrlSuffix(gcc/Warning-Options.html#index-Wdesignated-init)
>   
> --- gcc/c-family/c-opts.cc.jj	2024-11-23 13:00:28.188030262 +0100
> +++ gcc/c-family/c-opts.cc	2024-11-25 16:23:36.569829016 +0100
> @@ -1051,6 +1051,11 @@ c_common_post_options (const char **pfil
>   		       warn_deprecated_literal_operator,
>   		       deprecated_in (cxx23));
>   
> +  /* -Wdeprecated-variadic-comma-omission is enabled by default in C++26.  */
> +  SET_OPTION_IF_UNSET (&global_options, &global_options_set,
> +		       warn_deprecated_variadic_comma_omission,
> +		       deprecated_in (cxx26));
> +
>     /* -Wtemplate-id-cdtor is enabled by default in C++20.  */
>     SET_OPTION_IF_UNSET (&global_options, &global_options_set,
>   		       warn_template_id_cdtor,
> --- gcc/cp/parser.cc.jj	2024-11-23 13:00:29.060017680 +0100
> +++ gcc/cp/parser.cc	2024-11-25 17:02:24.551059305 +0100
> @@ -25667,6 +25667,16 @@ cp_parser_parameter_declaration_clause (
>        omitted.  */
>     else if (token->type == CPP_ELLIPSIS)
>       {
> +      /* Deprecated by P3176R1 in C++26.  */
> +      if (warn_deprecated_variadic_comma_omission)
> +	{
> +	  gcc_rich_location richloc (token->location);
> +	  richloc.add_fixit_insert_before (", ");
> +	  warning_at (&richloc, OPT_Wdeprecated_variadic_comma_omission,
> +		      "omission of %<,%> before varargs %<...%> is "
> +		      "deprecated in C++26");
> +	}
> +
>         /* Consume the `...' token.  */
>         cp_lexer_consume_token (parser->lexer);
>         /* And remember that we saw it.  */
> --- gcc/doc/invoke.texi.jj	2024-11-25 09:32:32.508139851 +0100
> +++ gcc/doc/invoke.texi	2024-11-25 17:23:57.269904929 +0100
> @@ -4081,6 +4081,22 @@ string operator "" _i18n(const char*, st
>   string operator ""_i18n(const char*, std::size_t); // preferred
>   @end smallexample
>   
> +@opindex Wdeprecated-variadic-comma-omission
> +@opindex Wno-deprecated-variadic-comma-omission
> +@item -Wdeprecated-variadic-comma-omission @r{(C++ and Objective-C++ only)}
> +Warn that omitting a comma before the varargs @code{...} at the end of
> +a function parameter list is deprecated.  This warning is enabled by
> +default in C++26, or with explicit @option{-Wdeprecated}.
> +
> +@smallexample
> +void f1(int...); // deprecated
> +void f1(int, ...); // preferred
> +template <typename ...T>
> +void f2(T...); // ok
> +template <typename ...T>
> +void f3(T......); // deprecated
> +@end smallexample
> +
>   @opindex Welaborated-enum-base
>   @opindex Wno-elaborated-enum-base
>   @item -Wno-elaborated-enum-base
> @@ -10349,8 +10365,9 @@ In C++, explicitly specifying @option{-W
>   warnings about some features that are deprecated in later language
>   standards, specifically @option{-Wcomma-subscript},
>   @option{-Wvolatile}, @option{-Wdeprecated-enum-float-conversion},
> -@option{-Wdeprecated-enum-enum-conversion}, and
> -@option{-Wdeprecated-literal-operator}.
> +@option{-Wdeprecated-enum-enum-conversion},
> +@option{-Wdeprecated-literal-operator}, and
> +@option{-Wdeprecated-variadic-comma-omission}.
>   
>   @opindex Wno-deprecated-declarations
>   @opindex Wdeprecated-declarations
> --- gcc/testsuite/g++.dg/cpp26/variadic-comma1.C.jj	2024-11-25 17:15:32.183991996 +0100
> +++ gcc/testsuite/g++.dg/cpp26/variadic-comma1.C	2024-11-25 17:15:05.824361844 +0100
> @@ -0,0 +1,18 @@
> +// P3176R1 - The Oxford variadic comma
> +// { dg-do compile { target c++11 } }
> +
> +void f1 (int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++26 } }
> +#if __cplusplus >= 202002L
> +void f2 (auto...);
> +void f3 (auto......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++26 } }
> +#endif
> +template <typename ...T>
> +void f4 (T......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++26 } }
> +template <typename ...T>
> +void f5 (T...);
> +template <typename ...T>
> +void f6 (T..., int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++26 } }
> +void
> +f7 (char...)			// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++26 } }
> +{
> +}
> --- gcc/testsuite/g++.dg/cpp26/variadic-comma2.C.jj	2024-11-25 17:24:31.058429656 +0100
> +++ gcc/testsuite/g++.dg/cpp26/variadic-comma2.C	2024-11-25 17:25:23.767688246 +0100
> @@ -0,0 +1,19 @@
> +// P3176R1 - The Oxford variadic comma
> +// { dg-do compile { target c++11 } }
> +// { dg-additional-options "-Wdeprecated" }
> +
> +void f1 (int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
> +#if __cplusplus >= 202002L
> +void f2 (auto...);
> +void f3 (auto......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++20 } }
> +#endif
> +template <typename ...T>
> +void f4 (T......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
> +template <typename ...T>
> +void f5 (T...);
> +template <typename ...T>
> +void f6 (T..., int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
> +void
> +f7 (char...)			// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
> +{
> +}
> --- gcc/testsuite/g++.dg/cpp26/variadic-comma3.C.jj	2024-11-25 22:01:42.057891012 +0100
> +++ gcc/testsuite/g++.dg/cpp26/variadic-comma3.C	2024-11-25 22:02:18.830383268 +0100
> @@ -0,0 +1,5 @@
> +// P3176R1 - The Oxford variadic comma
> +// { dg-do compile { target c++11 } }
> +// { dg-additional-options "-Wno-deprecated-variadic-comma-omission" }
> +
> +#include "variadic-comma1.C"
> --- gcc/testsuite/g++.dg/cpp26/variadic-comma4.C.jj	2024-11-25 22:02:29.682233427 +0100
> +++ gcc/testsuite/g++.dg/cpp26/variadic-comma4.C	2024-11-25 22:02:37.751122020 +0100
> @@ -0,0 +1,5 @@
> +// P3176R1 - The Oxford variadic comma
> +// { dg-do compile { target c++11 } }
> +// { dg-additional-options "-Wno-deprecated" }
> +
> +#include "variadic-comma1.C"
> --- gcc/testsuite/g++.dg/cpp26/variadic-comma5.C.jj	2024-11-25 22:03:50.871112402 +0100
> +++ gcc/testsuite/g++.dg/cpp26/variadic-comma5.C	2024-11-25 22:04:01.354967643 +0100
> @@ -0,0 +1,19 @@
> +// P3176R1 - The Oxford variadic comma
> +// { dg-do compile { target c++11 } }
> +// { dg-additional-options "-Wdeprecated-variadic-comma-omission" }
> +
> +void f1 (int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
> +#if __cplusplus >= 202002L
> +void f2 (auto...);
> +void f3 (auto......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++20 } }
> +#endif
> +template <typename ...T>
> +void f4 (T......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
> +template <typename ...T>
> +void f5 (T...);
> +template <typename ...T>
> +void f6 (T..., int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
> +void
> +f7 (char...)			// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
> +{
> +}
> --- gcc/testsuite/g++.dg/cpp1z/fold10.C.jj	2020-01-14 20:02:46.788609759 +0100
> +++ gcc/testsuite/g++.dg/cpp1z/fold10.C	2024-11-25 18:52:45.249601768 +0100
> @@ -4,7 +4,7 @@
>   template <int...> struct seq {};
>   template <bool> struct S {
>       template <typename Args>
> -    constexpr static void call(Args&&...) {}
> +    constexpr static void call(Args&&...) {}	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   };
>   
>   template <int ...Idx,typename ...Args>
> --- gcc/testsuite/g++.dg/ext/attrib33.C.jj	2020-01-14 20:02:46.827609175 +0100
> +++ gcc/testsuite/g++.dg/ext/attrib33.C	2024-11-25 18:53:32.785972918 +0100
> @@ -5,7 +5,7 @@
>   template <int N>
>   struct T
>   {
> -  void foo (char const * ...) __attribute__ ((format (printf,2,3)));
> +  void foo (char const * ...) __attribute__ ((format (printf,2,3)));	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   };
>   
>   template struct T<3>;
> --- gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic19.C.jj	2020-01-14 20:02:46.776609939 +0100
> +++ gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic19.C	2024-11-25 18:52:04.500140838 +0100
> @@ -1,4 +1,4 @@
>   // PR c++/86728
>   // { dg-do compile { target c++14 } }
>   
> -auto c = [](auto x ...) { };
> +auto c = [](auto x ...) { };	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
> --- gcc/testsuite/g++.dg/cpp2a/lambda-generic10.C.jj	2022-07-05 01:16:31.224175958 +0200
> +++ gcc/testsuite/g++.dg/cpp2a/lambda-generic10.C	2024-11-25 18:55:48.355179489 +0100
> @@ -4,7 +4,7 @@
>   void sink(...);
>   template <int... args> void f()
>   {
> -  sink ([] <int T> (int...) { return 1; }
> +  sink ([] <int T> (int...) { return 1; }	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>           .operator()<args>(args...)...); // { dg-warning "-Wmissing-template-keyword" }
>   } // { dg-prune-output {expected '\)'} }
>   
> --- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C.jj	2020-01-14 20:02:46.736610538 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C	2024-11-25 18:50:36.356306884 +0100
> @@ -7,7 +7,7 @@ struct FF
>   {
>     template < class F, class ... Ts >
>     void
> -  operator () (F & ...)
> +  operator () (F & ...)			// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>     {
>       const int n = sizeof ... (Ts) + 1;
>       void *mutexes[n];
> --- gcc/testsuite/g++.dg/cpp0x/variadic164.C.jj	2020-01-14 20:02:46.765610104 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/variadic164.C	2024-11-25 19:05:56.218138142 +0100
> @@ -8,5 +8,5 @@ template <typename Tuple, typename... Tu
>             typename =
>                 typename tuple<slice_result<ElementIndices, Tuples...>,
>                                slice_result<ElementIndices, Tuples...>...>::type> // { dg-error "parameter pack" }
> -void zip_with(Tuple...);
> +void zip_with(Tuple...);	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   decltype(zip_with(0)) d;	// { dg-error "no match" }
> --- gcc/testsuite/g++.dg/cpp0x/variadic17.C.jj	2020-01-14 20:02:46.765610104 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/variadic17.C	2024-11-25 18:47:20.490015632 +0100
> @@ -2,7 +2,7 @@
>   template<typename R, typename... ArgTypes>
>   struct make_function_type
>   {
> -  typedef R type(const ArgTypes&......);
> +  typedef R type(const ArgTypes&......);		// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   };
>   
>   template<typename T, typename U>
> @@ -16,6 +16,6 @@ struct is_same<T, T> {
>   };
>   
>   int a0[is_same<make_function_type<int>::type, int(...)>::value? 1 : -1];
> -int a1[is_same<make_function_type<int, float>::type, int(const float&...)>::value? 1 : -1];
> +int a1[is_same<make_function_type<int, float>::type, int(const float&...)>::value? 1 : -1];		// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   int a2[is_same<make_function_type<int, float>::type, int(const float&,...)>::value? 1 : -1];
> -int a3[is_same<make_function_type<int, float, double>::type, int(const float&, double const&...)>::value? 1 : -1];
> +int a3[is_same<make_function_type<int, float, double>::type, int(const float&, double const&...)>::value? 1 : -1];		// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
> --- gcc/testsuite/g++.dg/cpp0x/udlit-args-neg.C.jj	2024-10-03 20:10:07.389515318 +0200
> +++ gcc/testsuite/g++.dg/cpp0x/udlit-args-neg.C	2024-11-25 18:43:59.218836567 +0100
> @@ -27,6 +27,7 @@ operator ""_Foo(const char16_t *);	// {
>   
>   Foo
>   operator ""_Foo(char...);	// { dg-error "1:.Foo operator\"\"_Foo\\(char, \\.\\.\\.\\). has invalid argument list" }
> +				// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } .-1 }
>   
>   Foo
>   operator ""_Foo(unsigned long long int, char);	// { dg-error "1:.Foo operator\"\"_Foo\\(long long unsigned int, char\\). has invalid argument list" }
> --- gcc/testsuite/g++.dg/cpp0x/variadic28.C.jj	2020-01-14 20:02:46.766610088 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/variadic28.C	2024-11-25 18:49:39.892061844 +0100
> @@ -3,7 +3,7 @@ template<typename Signature>
>   struct function_traits;
>   
>   template<typename R, typename... ArgTypes>
> -struct function_traits<R(ArgTypes......)> {
> +struct function_traits<R(ArgTypes......)> {	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>     typedef R result_type;
>   };
>   
> @@ -17,9 +17,9 @@ struct same_type<T, T> {
>     static const bool value = true;
>   };
>   
> -int a0[same_type<function_traits<int(double, char...)>::result_type, int>::value? 1 : -1];
> +int a0[same_type<function_traits<int(double, char...)>::result_type, int>::value? 1 : -1];	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   int a1[same_type<function_traits<int(double, char,...)>::result_type, int>::value? 1 : -1];
>   int a2[same_type<function_traits<int(char,...)>::result_type, int>::value? 1 : -1];
>   int a3[same_type<function_traits<int(...)>::result_type, int>::value? 1 : -1];
> -int a4[same_type<function_traits<int(double x, char...)>::result_type, int>::value? 1 : -1];
> -int a5[same_type<function_traits<int(double, char y...)>::result_type, int>::value? 1 : -1];
> +int a4[same_type<function_traits<int(double x, char...)>::result_type, int>::value? 1 : -1];	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
> +int a5[same_type<function_traits<int(double, char y...)>::result_type, int>::value? 1 : -1];	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
> --- gcc/testsuite/g++.dg/cpp0x/gen-attrs-33.C.jj	2020-01-14 20:02:46.728610658 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-33.C	2024-11-25 18:48:05.083390637 +0100
> @@ -5,7 +5,7 @@
>   template <int N>
>   struct T
>   {
> -  void foo [[gnu::format (printf,2,3)]] (char const * ...);
> +  void foo [[gnu::format (printf,2,3)]] (char const * ...);	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   };
>   
>   template struct T<3>;
> --- gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C.jj	2024-03-08 21:36:57.766117003 +0100
> +++ gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C	2024-11-25 19:00:29.416461364 +0100
> @@ -24,7 +24,7 @@ void S::f12(this S s = {}) {} // { dg-er
>   
>   struct S0 {
>     template<typename Selves>
> -  void f(this Selves...) {}
> +  void f(this Selves...) {}	    // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   
>     template<typename Selves>
>     void g(this Selves... selves) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -37,7 +37,7 @@ struct S0 {
>     void k(this Selves...) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>   
>     template<typename Selves>
> -  void fd(this Selves...);
> +  void fd(this Selves...);	   // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   
>     template<typename Selves>
>     void gd(this Selves... selves);  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -52,7 +52,7 @@ struct S0 {
>   
>   struct S1 {
>     template<typename Selves>
> -  void f(this Selves&...) {}
> +  void f(this Selves&...) {}	     // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   
>     template<typename Selves>
>     void g(this Selves&... selves) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -65,7 +65,7 @@ struct S1 {
>     void k(this Selves&...) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>   
>     template<typename Selves>
> -  void fd(this Selves&...);
> +  void fd(this Selves&...);	    // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   
>     template<typename Selves>
>     void gd(this Selves&... selves);  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -80,7 +80,7 @@ struct S1 {
>   
>   struct S2 {
>     template<typename Selves>
> -  void f(this Selves&&...) {}
> +  void f(this Selves&&...) {}	      // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   
>     template<typename Selves>
>     void g(this Selves&&... selves) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -93,7 +93,7 @@ struct S2 {
>     void k(this Selves&&...) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>   
>     template<typename Selves>
> -  void fd(this Selves&&...);
> +  void fd(this Selves&&...);	     // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   
>     template<typename Selves>
>     void gd(this Selves&&... selves);  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -108,7 +108,7 @@ struct S2 {
>   
>   struct S3 {
>     template<typename Selves>
> -  void f(this Selves const&...) {}
> +  void f(this Selves const&...) {}	   // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   
>     template<typename Selves>
>     void g(this Selves const&... selves) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -121,7 +121,7 @@ struct S3 {
>     void k(this Selves const&...) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>   
>     template<typename Selves>
> -  void fd(this Selves const&...);
> +  void fd(this Selves const&...);	  // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   
>     template<typename Selves>
>     void gd(this Selves const&... selves);  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -136,7 +136,7 @@ struct S3 {
>   
>   struct S4 {
>     template<typename Selves>
> -  void f(this Selves const&&...) {}
> +  void f(this Selves const&&...) {}	    // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   
>     template<typename Selves>
>     void g(this Selves const&&... selves) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> @@ -149,7 +149,7 @@ struct S4 {
>     void k(this Selves const&&...) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
>   
>     template<typename Selves>
> -  void fd(this Selves const&&...);
> +  void fd(this Selves const&&...);	   // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   
>     template<typename Selves>
>     void gd(this Selves const&&... selves);  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
> --- gcc/testsuite/g++.old-deja/g++.law/operators15.C.jj	2020-01-14 20:02:47.045605909 +0100
> +++ gcc/testsuite/g++.old-deja/g++.law/operators15.C	2024-11-25 19:01:12.574890431 +0100
> @@ -6,7 +6,7 @@
>   // Subject: bug report
>   // Date: Wed, 27 Jan 1993 16:37:30 -0500
>   
> -extern "C" int printf(const char* ...);
> +extern "C" int printf(const char* ...);	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>   
>   int     delete_counter = -1;
>   
> --- gcc/testsuite/g++.old-deja/g++.mike/p811.C.jj	2020-01-14 20:02:47.056605744 +0100
> +++ gcc/testsuite/g++.old-deja/g++.mike/p811.C	2024-11-25 19:02:39.325742809 +0100
> @@ -305,7 +305,7 @@ class ostream : public ios
>       ostream& seekp(streampos);
>       ostream& seekp(streamoff, _seek_dir);
>       streampos tellp();
> -    ostream& form(const char *format ...);
> +    ostream& form(const char *format ...);		// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>       ostream& vform(const char *format, char*  args);
>   };
>   
> @@ -460,7 +460,7 @@ class iostream : public ios {
>   	{ return ((ostream*)this)->write((char*)s, n); }
>       ostream& write(const void *s, int n)
>   	{ return ((ostream*)this)->write((char*)s, n); }
> -    ostream& form(const char *format ...);
> +    ostream& form(const char *format ...);		// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
>       ostream& vform(const char *format, char*  args)
>   	{ return ((ostream*)this)->vform(format, args); }
>       ostream& seekp(streampos pos) { return ((ostream*)this)->seekp(pos); }
> --- gcc/testsuite/g++.old-deja/g++.mike/p12306.C.jj	2020-01-14 20:02:47.053605789 +0100
> +++ gcc/testsuite/g++.old-deja/g++.mike/p12306.C	2024-11-25 19:01:43.748478035 +0100
> @@ -4,7 +4,7 @@
>   void *ptr1, *ptr2;
>   int fail = 0;
>   
> -extern "C" int printf(const char *...);
> +extern "C" int printf(const char *, ...);
>   
>   class RWSlist { };
>   
> --- gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C.jj	2022-11-22 22:55:49.015481942 +0100
> +++ gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C	2024-11-25 18:42:20.294223050 +0100
> @@ -7,5 +7,5 @@ struct _Bind {
>     _Bind(_Bind &);
>   };
>   template <typename _Func, typename _BoundArgs>
> -_Bind bind(_Func, _BoundArgs &&...);
> +_Bind bind(_Func, _BoundArgs &&, ...);
>   void test01() { bind(minus(), _2, _1); }
> --- gcc/testsuite/g++.dg/cpp0x/vt-65790.C.jj	2020-01-14 20:02:46.769610044 +0100
> +++ gcc/testsuite/g++.dg/cpp0x/vt-65790.C	2024-11-25 18:48:42.594864893 +0100
> @@ -1,7 +1,7 @@
>   // PR c++/65790
>   // { dg-do compile { target c++11 } }
>   
> -extern "C" int printf(const char* ...);
> +extern "C" int printf(const char*, ...);
>   
>   namespace std
>   {
> --- libstdc++-v3/include/std/functional.jj	2024-09-25 17:25:07.245360363 +0200
> +++ libstdc++-v3/include/std/functional	2024-11-25 17:56:40.680321230 +0100
> @@ -841,7 +841,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>       };
>   
>     template<typename _Ret, typename... _Args, typename... _BoundArgs>
> -    struct _Bind_check_arity<_Ret (*)(_Args......), _BoundArgs...>
> +    struct _Bind_check_arity<_Ret (*)(_Args..., ...), _BoundArgs...>
>       {
>         static_assert(sizeof...(_BoundArgs) >= sizeof...(_Args),
>                      "Wrong number of arguments for function");
> --- libstdc++-v3/include/bits/refwrap.h.jj	2024-09-25 17:25:07.222360675 +0200
> +++ libstdc++-v3/include/bits/refwrap.h	2024-11-25 17:56:11.244734208 +0100
> @@ -94,7 +94,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>         using __vararg = false_type;					\
>       };									\
>     template<typename _Res, typename _Class, typename... _ArgTypes>	\
> -    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes... ...) _CV _REF>	\
> +    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes..., ...) _CV _REF>	\
>       : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...>		\
>       {									\
>         using __vararg = true_type;					\
> @@ -145,7 +145,8 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, fals
>   
>     /// Retrieve the result type for a varargs function type.
>     template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
> -    struct _Weak_result_type_impl<_Res(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL>
> +    struct _Weak_result_type_impl<_Res(_ArgTypes...,
> +				       ...) _GLIBCXX_NOEXCEPT_QUAL>
>       { typedef _Res result_type; };
>   
>     /// Retrieve the result type for a function pointer.
> @@ -156,7 +157,7 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, fals
>     /// Retrieve the result type for a varargs function pointer.
>     template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
>       struct
> -    _Weak_result_type_impl<_Res(*)(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL>
> +    _Weak_result_type_impl<_Res(*)(_ArgTypes..., ...) _GLIBCXX_NOEXCEPT_QUAL>
>       { typedef _Res result_type; };
>   
>     // Let _Weak_result_type_impl perform the real work.
> --- libstdc++-v3/include/tr1/type_traits.jj	2024-10-01 00:09:07.468746064 +0200
> +++ libstdc++-v3/include/tr1/type_traits	2024-11-25 17:57:41.059474123 +0100
> @@ -235,25 +235,24 @@ namespace tr1
>       struct is_function<_Res(_ArgTypes...)>
>       : public true_type { };
>     template<typename _Res, typename... _ArgTypes>
> -    struct is_function<_Res(_ArgTypes......)>
> -    : public true_type { };
> +    struct is_function<_Res(_ArgTypes..., ...)> : public true_type { };
>     template<typename _Res, typename... _ArgTypes>
>       struct is_function<_Res(_ArgTypes...) const>
>       : public true_type { };
>     template<typename _Res, typename... _ArgTypes>
> -    struct is_function<_Res(_ArgTypes......) const>
> +    struct is_function<_Res(_ArgTypes..., ...) const>
>       : public true_type { };
>     template<typename _Res, typename... _ArgTypes>
>       struct is_function<_Res(_ArgTypes...) volatile>
>       : public true_type { };
>     template<typename _Res, typename... _ArgTypes>
> -    struct is_function<_Res(_ArgTypes......) volatile>
> +    struct is_function<_Res(_ArgTypes..., ...) volatile>
>       : public true_type { };
>     template<typename _Res, typename... _ArgTypes>
>       struct is_function<_Res(_ArgTypes...) const volatile>
>       : public true_type { };
>     template<typename _Res, typename... _ArgTypes>
> -    struct is_function<_Res(_ArgTypes......) const volatile>
> +    struct is_function<_Res(_ArgTypes..., ...) const volatile>
>       : public true_type { };
>   
>     // composite type traits [4.5.2].
> 
> 
> 	Jakub
>
  

Patch

--- gcc/c-family/c.opt.jj	2024-11-22 19:52:19.477579338 +0100
+++ gcc/c-family/c.opt	2024-11-25 16:22:11.325028058 +0100
@@ -672,6 +672,10 @@  Wdeprecated-non-prototype
 C ObjC Var(warn_deprecated_non_prototype) Init(-1) Warning
 Warn about calls with arguments to functions declared without parameters.
 
+Wdeprecated-variadic-comma-omission
+C++ ObjC++ Var(warn_deprecated_variadic_comma_omission) Warning
+Warn about deprecated omission of comma before ... in varargs function declaration.
+
 Wdesignated-init
 C ObjC Var(warn_designated_init) Init(1) Warning
 Warn about positional initialization of structs requiring designated initializers.
--- gcc/c-family/c.opt.urls.jj	2024-11-18 21:59:35.872150269 +0100
+++ gcc/c-family/c.opt.urls	2024-11-25 17:38:25.396693802 +0100
@@ -310,6 +310,9 @@  UrlSuffix(gcc/C_002b_002b-Dialect-Option
 Wdeprecated-non-prototype
 UrlSuffix(gcc/Warning-Options.html#index-Wdeprecated-non-prototype)
 
+Wdeprecated-variadic-comma-omission
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wdeprecated-variadic-comma-omission)
+
 Wdesignated-init
 UrlSuffix(gcc/Warning-Options.html#index-Wdesignated-init)
 
--- gcc/c-family/c-opts.cc.jj	2024-11-23 13:00:28.188030262 +0100
+++ gcc/c-family/c-opts.cc	2024-11-25 16:23:36.569829016 +0100
@@ -1051,6 +1051,11 @@  c_common_post_options (const char **pfil
 		       warn_deprecated_literal_operator,
 		       deprecated_in (cxx23));
 
+  /* -Wdeprecated-variadic-comma-omission is enabled by default in C++26.  */
+  SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+		       warn_deprecated_variadic_comma_omission,
+		       deprecated_in (cxx26));
+
   /* -Wtemplate-id-cdtor is enabled by default in C++20.  */
   SET_OPTION_IF_UNSET (&global_options, &global_options_set,
 		       warn_template_id_cdtor,
--- gcc/cp/parser.cc.jj	2024-11-23 13:00:29.060017680 +0100
+++ gcc/cp/parser.cc	2024-11-25 17:02:24.551059305 +0100
@@ -25667,6 +25667,16 @@  cp_parser_parameter_declaration_clause (
      omitted.  */
   else if (token->type == CPP_ELLIPSIS)
     {
+      /* Deprecated by P3176R1 in C++26.  */
+      if (warn_deprecated_variadic_comma_omission)
+	{
+	  gcc_rich_location richloc (token->location);
+	  richloc.add_fixit_insert_before (", ");
+	  warning_at (&richloc, OPT_Wdeprecated_variadic_comma_omission,
+		      "omission of %<,%> before varargs %<...%> is "
+		      "deprecated in C++26");
+	}
+
       /* Consume the `...' token.  */
       cp_lexer_consume_token (parser->lexer);
       /* And remember that we saw it.  */
--- gcc/doc/invoke.texi.jj	2024-11-25 09:32:32.508139851 +0100
+++ gcc/doc/invoke.texi	2024-11-25 17:23:57.269904929 +0100
@@ -4081,6 +4081,22 @@  string operator "" _i18n(const char*, st
 string operator ""_i18n(const char*, std::size_t); // preferred
 @end smallexample
 
+@opindex Wdeprecated-variadic-comma-omission
+@opindex Wno-deprecated-variadic-comma-omission
+@item -Wdeprecated-variadic-comma-omission @r{(C++ and Objective-C++ only)}
+Warn that omitting a comma before the varargs @code{...} at the end of
+a function parameter list is deprecated.  This warning is enabled by
+default in C++26, or with explicit @option{-Wdeprecated}.
+
+@smallexample
+void f1(int...); // deprecated
+void f1(int, ...); // preferred
+template <typename ...T>
+void f2(T...); // ok
+template <typename ...T>
+void f3(T......); // deprecated
+@end smallexample
+
 @opindex Welaborated-enum-base
 @opindex Wno-elaborated-enum-base
 @item -Wno-elaborated-enum-base
@@ -10349,8 +10365,9 @@  In C++, explicitly specifying @option{-W
 warnings about some features that are deprecated in later language
 standards, specifically @option{-Wcomma-subscript},
 @option{-Wvolatile}, @option{-Wdeprecated-enum-float-conversion},
-@option{-Wdeprecated-enum-enum-conversion}, and
-@option{-Wdeprecated-literal-operator}.
+@option{-Wdeprecated-enum-enum-conversion},
+@option{-Wdeprecated-literal-operator}, and
+@option{-Wdeprecated-variadic-comma-omission}.
 
 @opindex Wno-deprecated-declarations
 @opindex Wdeprecated-declarations
--- gcc/testsuite/g++.dg/cpp26/variadic-comma1.C.jj	2024-11-25 17:15:32.183991996 +0100
+++ gcc/testsuite/g++.dg/cpp26/variadic-comma1.C	2024-11-25 17:15:05.824361844 +0100
@@ -0,0 +1,18 @@ 
+// P3176R1 - The Oxford variadic comma
+// { dg-do compile { target c++11 } }
+
+void f1 (int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++26 } }
+#if __cplusplus >= 202002L
+void f2 (auto...);
+void f3 (auto......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++26 } }
+#endif
+template <typename ...T>
+void f4 (T......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++26 } }
+template <typename ...T>
+void f5 (T...);
+template <typename ...T>
+void f6 (T..., int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++26 } }
+void
+f7 (char...)			// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++26 } }
+{
+}
--- gcc/testsuite/g++.dg/cpp26/variadic-comma2.C.jj	2024-11-25 17:24:31.058429656 +0100
+++ gcc/testsuite/g++.dg/cpp26/variadic-comma2.C	2024-11-25 17:25:23.767688246 +0100
@@ -0,0 +1,19 @@ 
+// P3176R1 - The Oxford variadic comma
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wdeprecated" }
+
+void f1 (int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
+#if __cplusplus >= 202002L
+void f2 (auto...);
+void f3 (auto......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++20 } }
+#endif
+template <typename ...T>
+void f4 (T......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
+template <typename ...T>
+void f5 (T...);
+template <typename ...T>
+void f6 (T..., int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
+void
+f7 (char...)			// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
+{
+}
--- gcc/testsuite/g++.dg/cpp26/variadic-comma3.C.jj	2024-11-25 22:01:42.057891012 +0100
+++ gcc/testsuite/g++.dg/cpp26/variadic-comma3.C	2024-11-25 22:02:18.830383268 +0100
@@ -0,0 +1,5 @@ 
+// P3176R1 - The Oxford variadic comma
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-deprecated-variadic-comma-omission" }
+
+#include "variadic-comma1.C"
--- gcc/testsuite/g++.dg/cpp26/variadic-comma4.C.jj	2024-11-25 22:02:29.682233427 +0100
+++ gcc/testsuite/g++.dg/cpp26/variadic-comma4.C	2024-11-25 22:02:37.751122020 +0100
@@ -0,0 +1,5 @@ 
+// P3176R1 - The Oxford variadic comma
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-deprecated" }
+
+#include "variadic-comma1.C"
--- gcc/testsuite/g++.dg/cpp26/variadic-comma5.C.jj	2024-11-25 22:03:50.871112402 +0100
+++ gcc/testsuite/g++.dg/cpp26/variadic-comma5.C	2024-11-25 22:04:01.354967643 +0100
@@ -0,0 +1,19 @@ 
+// P3176R1 - The Oxford variadic comma
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wdeprecated-variadic-comma-omission" }
+
+void f1 (int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
+#if __cplusplus >= 202002L
+void f2 (auto...);
+void f3 (auto......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" "" { target c++20 } }
+#endif
+template <typename ...T>
+void f4 (T......);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
+template <typename ...T>
+void f5 (T...);
+template <typename ...T>
+void f6 (T..., int...);		// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
+void
+f7 (char...)			// { dg-warning "omission of ',' before varargs '...' is deprecated in" }
+{
+}
--- gcc/testsuite/g++.dg/cpp1z/fold10.C.jj	2020-01-14 20:02:46.788609759 +0100
+++ gcc/testsuite/g++.dg/cpp1z/fold10.C	2024-11-25 18:52:45.249601768 +0100
@@ -4,7 +4,7 @@ 
 template <int...> struct seq {};
 template <bool> struct S {
     template <typename Args>
-    constexpr static void call(Args&&...) {}
+    constexpr static void call(Args&&...) {}	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 };
 
 template <int ...Idx,typename ...Args>
--- gcc/testsuite/g++.dg/ext/attrib33.C.jj	2020-01-14 20:02:46.827609175 +0100
+++ gcc/testsuite/g++.dg/ext/attrib33.C	2024-11-25 18:53:32.785972918 +0100
@@ -5,7 +5,7 @@ 
 template <int N>
 struct T
 {
-  void foo (char const * ...) __attribute__ ((format (printf,2,3)));
+  void foo (char const * ...) __attribute__ ((format (printf,2,3)));	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 };
 
 template struct T<3>;
--- gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic19.C.jj	2020-01-14 20:02:46.776609939 +0100
+++ gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic19.C	2024-11-25 18:52:04.500140838 +0100
@@ -1,4 +1,4 @@ 
 // PR c++/86728
 // { dg-do compile { target c++14 } }
 
-auto c = [](auto x ...) { };
+auto c = [](auto x ...) { };	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
--- gcc/testsuite/g++.dg/cpp2a/lambda-generic10.C.jj	2022-07-05 01:16:31.224175958 +0200
+++ gcc/testsuite/g++.dg/cpp2a/lambda-generic10.C	2024-11-25 18:55:48.355179489 +0100
@@ -4,7 +4,7 @@ 
 void sink(...);
 template <int... args> void f()
 {
-  sink ([] <int T> (int...) { return 1; }
+  sink ([] <int T> (int...) { return 1; }	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
         .operator()<args>(args...)...); // { dg-warning "-Wmissing-template-keyword" }
 } // { dg-prune-output {expected '\)'} }
 
--- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C.jj	2020-01-14 20:02:46.736610538 +0100
+++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C	2024-11-25 18:50:36.356306884 +0100
@@ -7,7 +7,7 @@  struct FF
 {
   template < class F, class ... Ts >
   void
-  operator () (F & ...)
+  operator () (F & ...)			// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
   {
     const int n = sizeof ... (Ts) + 1;
     void *mutexes[n];
--- gcc/testsuite/g++.dg/cpp0x/variadic164.C.jj	2020-01-14 20:02:46.765610104 +0100
+++ gcc/testsuite/g++.dg/cpp0x/variadic164.C	2024-11-25 19:05:56.218138142 +0100
@@ -8,5 +8,5 @@  template <typename Tuple, typename... Tu
           typename =
               typename tuple<slice_result<ElementIndices, Tuples...>,
                              slice_result<ElementIndices, Tuples...>...>::type> // { dg-error "parameter pack" }
-void zip_with(Tuple...);
+void zip_with(Tuple...);	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 decltype(zip_with(0)) d;	// { dg-error "no match" }
--- gcc/testsuite/g++.dg/cpp0x/variadic17.C.jj	2020-01-14 20:02:46.765610104 +0100
+++ gcc/testsuite/g++.dg/cpp0x/variadic17.C	2024-11-25 18:47:20.490015632 +0100
@@ -2,7 +2,7 @@ 
 template<typename R, typename... ArgTypes>
 struct make_function_type
 {
-  typedef R type(const ArgTypes&......);
+  typedef R type(const ArgTypes&......);		// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 };
 
 template<typename T, typename U>
@@ -16,6 +16,6 @@  struct is_same<T, T> {
 };
 
 int a0[is_same<make_function_type<int>::type, int(...)>::value? 1 : -1];
-int a1[is_same<make_function_type<int, float>::type, int(const float&...)>::value? 1 : -1];
+int a1[is_same<make_function_type<int, float>::type, int(const float&...)>::value? 1 : -1];		// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 int a2[is_same<make_function_type<int, float>::type, int(const float&,...)>::value? 1 : -1];
-int a3[is_same<make_function_type<int, float, double>::type, int(const float&, double const&...)>::value? 1 : -1];
+int a3[is_same<make_function_type<int, float, double>::type, int(const float&, double const&...)>::value? 1 : -1];		// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
--- gcc/testsuite/g++.dg/cpp0x/udlit-args-neg.C.jj	2024-10-03 20:10:07.389515318 +0200
+++ gcc/testsuite/g++.dg/cpp0x/udlit-args-neg.C	2024-11-25 18:43:59.218836567 +0100
@@ -27,6 +27,7 @@  operator ""_Foo(const char16_t *);	// {
 
 Foo
 operator ""_Foo(char...);	// { dg-error "1:.Foo operator\"\"_Foo\\(char, \\.\\.\\.\\). has invalid argument list" }
+				// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } .-1 }
 
 Foo
 operator ""_Foo(unsigned long long int, char);	// { dg-error "1:.Foo operator\"\"_Foo\\(long long unsigned int, char\\). has invalid argument list" }
--- gcc/testsuite/g++.dg/cpp0x/variadic28.C.jj	2020-01-14 20:02:46.766610088 +0100
+++ gcc/testsuite/g++.dg/cpp0x/variadic28.C	2024-11-25 18:49:39.892061844 +0100
@@ -3,7 +3,7 @@  template<typename Signature>
 struct function_traits;
 
 template<typename R, typename... ArgTypes>
-struct function_traits<R(ArgTypes......)> {
+struct function_traits<R(ArgTypes......)> {	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
   typedef R result_type;
 };
 
@@ -17,9 +17,9 @@  struct same_type<T, T> {
   static const bool value = true;
 };
 
-int a0[same_type<function_traits<int(double, char...)>::result_type, int>::value? 1 : -1];
+int a0[same_type<function_traits<int(double, char...)>::result_type, int>::value? 1 : -1];	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 int a1[same_type<function_traits<int(double, char,...)>::result_type, int>::value? 1 : -1];
 int a2[same_type<function_traits<int(char,...)>::result_type, int>::value? 1 : -1];
 int a3[same_type<function_traits<int(...)>::result_type, int>::value? 1 : -1];
-int a4[same_type<function_traits<int(double x, char...)>::result_type, int>::value? 1 : -1];
-int a5[same_type<function_traits<int(double, char y...)>::result_type, int>::value? 1 : -1];
+int a4[same_type<function_traits<int(double x, char...)>::result_type, int>::value? 1 : -1];	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
+int a5[same_type<function_traits<int(double, char y...)>::result_type, int>::value? 1 : -1];	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
--- gcc/testsuite/g++.dg/cpp0x/gen-attrs-33.C.jj	2020-01-14 20:02:46.728610658 +0100
+++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-33.C	2024-11-25 18:48:05.083390637 +0100
@@ -5,7 +5,7 @@ 
 template <int N>
 struct T
 {
-  void foo [[gnu::format (printf,2,3)]] (char const * ...);
+  void foo [[gnu::format (printf,2,3)]] (char const * ...);	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 };
 
 template struct T<3>;
--- gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C.jj	2024-03-08 21:36:57.766117003 +0100
+++ gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C	2024-11-25 19:00:29.416461364 +0100
@@ -24,7 +24,7 @@  void S::f12(this S s = {}) {} // { dg-er
 
 struct S0 {
   template<typename Selves>
-  void f(this Selves...) {}
+  void f(this Selves...) {}	    // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 
   template<typename Selves>
   void g(this Selves... selves) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
@@ -37,7 +37,7 @@  struct S0 {
   void k(this Selves...) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
 
   template<typename Selves>
-  void fd(this Selves...);
+  void fd(this Selves...);	   // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 
   template<typename Selves>
   void gd(this Selves... selves);  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
@@ -52,7 +52,7 @@  struct S0 {
 
 struct S1 {
   template<typename Selves>
-  void f(this Selves&...) {}
+  void f(this Selves&...) {}	     // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 
   template<typename Selves>
   void g(this Selves&... selves) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
@@ -65,7 +65,7 @@  struct S1 {
   void k(this Selves&...) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
 
   template<typename Selves>
-  void fd(this Selves&...);
+  void fd(this Selves&...);	    // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 
   template<typename Selves>
   void gd(this Selves&... selves);  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
@@ -80,7 +80,7 @@  struct S1 {
 
 struct S2 {
   template<typename Selves>
-  void f(this Selves&&...) {}
+  void f(this Selves&&...) {}	      // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 
   template<typename Selves>
   void g(this Selves&&... selves) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
@@ -93,7 +93,7 @@  struct S2 {
   void k(this Selves&&...) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
 
   template<typename Selves>
-  void fd(this Selves&&...);
+  void fd(this Selves&&...);	     // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 
   template<typename Selves>
   void gd(this Selves&&... selves);  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
@@ -108,7 +108,7 @@  struct S2 {
 
 struct S3 {
   template<typename Selves>
-  void f(this Selves const&...) {}
+  void f(this Selves const&...) {}	   // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 
   template<typename Selves>
   void g(this Selves const&... selves) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
@@ -121,7 +121,7 @@  struct S3 {
   void k(this Selves const&...) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
 
   template<typename Selves>
-  void fd(this Selves const&...);
+  void fd(this Selves const&...);	  // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 
   template<typename Selves>
   void gd(this Selves const&... selves);  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
@@ -136,7 +136,7 @@  struct S3 {
 
 struct S4 {
   template<typename Selves>
-  void f(this Selves const&&...) {}
+  void f(this Selves const&&...) {}	    // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 
   template<typename Selves>
   void g(this Selves const&&... selves) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
@@ -149,7 +149,7 @@  struct S4 {
   void k(this Selves const&&...) {}  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
 
   template<typename Selves>
-  void fd(this Selves const&&...);
+  void fd(this Selves const&&...);	   // { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 
   template<typename Selves>
   void gd(this Selves const&&... selves);  // { dg-error "an explicit object parameter cannot be a function parameter pack" }
--- gcc/testsuite/g++.old-deja/g++.law/operators15.C.jj	2020-01-14 20:02:47.045605909 +0100
+++ gcc/testsuite/g++.old-deja/g++.law/operators15.C	2024-11-25 19:01:12.574890431 +0100
@@ -6,7 +6,7 @@ 
 // Subject: bug report
 // Date: Wed, 27 Jan 1993 16:37:30 -0500
 
-extern "C" int printf(const char* ...);
+extern "C" int printf(const char* ...);	// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
 
 int     delete_counter = -1;
 
--- gcc/testsuite/g++.old-deja/g++.mike/p811.C.jj	2020-01-14 20:02:47.056605744 +0100
+++ gcc/testsuite/g++.old-deja/g++.mike/p811.C	2024-11-25 19:02:39.325742809 +0100
@@ -305,7 +305,7 @@  class ostream : public ios
     ostream& seekp(streampos);
     ostream& seekp(streamoff, _seek_dir);
     streampos tellp();
-    ostream& form(const char *format ...);
+    ostream& form(const char *format ...);		// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
     ostream& vform(const char *format, char*  args);
 };
 
@@ -460,7 +460,7 @@  class iostream : public ios {
 	{ return ((ostream*)this)->write((char*)s, n); }
     ostream& write(const void *s, int n)
 	{ return ((ostream*)this)->write((char*)s, n); }
-    ostream& form(const char *format ...);
+    ostream& form(const char *format ...);		// { dg-warning "omission of ',' before varargs '...' is deprecated" "" { target c++26 } }
     ostream& vform(const char *format, char*  args)
 	{ return ((ostream*)this)->vform(format, args); }
     ostream& seekp(streampos pos) { return ((ostream*)this)->seekp(pos); }
--- gcc/testsuite/g++.old-deja/g++.mike/p12306.C.jj	2020-01-14 20:02:47.053605789 +0100
+++ gcc/testsuite/g++.old-deja/g++.mike/p12306.C	2024-11-25 19:01:43.748478035 +0100
@@ -4,7 +4,7 @@ 
 void *ptr1, *ptr2;
 int fail = 0;
 
-extern "C" int printf(const char *...);
+extern "C" int printf(const char *, ...);
 
 class RWSlist { };
 
--- gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C.jj	2022-11-22 22:55:49.015481942 +0100
+++ gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C	2024-11-25 18:42:20.294223050 +0100
@@ -7,5 +7,5 @@  struct _Bind {
   _Bind(_Bind &);
 };
 template <typename _Func, typename _BoundArgs>
-_Bind bind(_Func, _BoundArgs &&...);
+_Bind bind(_Func, _BoundArgs &&, ...);
 void test01() { bind(minus(), _2, _1); }
--- gcc/testsuite/g++.dg/cpp0x/vt-65790.C.jj	2020-01-14 20:02:46.769610044 +0100
+++ gcc/testsuite/g++.dg/cpp0x/vt-65790.C	2024-11-25 18:48:42.594864893 +0100
@@ -1,7 +1,7 @@ 
 // PR c++/65790
 // { dg-do compile { target c++11 } }
 
-extern "C" int printf(const char* ...);
+extern "C" int printf(const char*, ...);
 
 namespace std
 {
--- libstdc++-v3/include/std/functional.jj	2024-09-25 17:25:07.245360363 +0200
+++ libstdc++-v3/include/std/functional	2024-11-25 17:56:40.680321230 +0100
@@ -841,7 +841,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   template<typename _Ret, typename... _Args, typename... _BoundArgs>
-    struct _Bind_check_arity<_Ret (*)(_Args......), _BoundArgs...>
+    struct _Bind_check_arity<_Ret (*)(_Args..., ...), _BoundArgs...>
     {
       static_assert(sizeof...(_BoundArgs) >= sizeof...(_Args),
                    "Wrong number of arguments for function");
--- libstdc++-v3/include/bits/refwrap.h.jj	2024-09-25 17:25:07.222360675 +0200
+++ libstdc++-v3/include/bits/refwrap.h	2024-11-25 17:56:11.244734208 +0100
@@ -94,7 +94,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __vararg = false_type;					\
     };									\
   template<typename _Res, typename _Class, typename... _ArgTypes>	\
-    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes... ...) _CV _REF>	\
+    struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes..., ...) _CV _REF>	\
     : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...>		\
     {									\
       using __vararg = true_type;					\
@@ -145,7 +145,8 @@  _GLIBCXX_MEM_FN_TRAITS(&& noexcept, fals
 
   /// Retrieve the result type for a varargs function type.
   template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
-    struct _Weak_result_type_impl<_Res(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL>
+    struct _Weak_result_type_impl<_Res(_ArgTypes...,
+				       ...) _GLIBCXX_NOEXCEPT_QUAL>
     { typedef _Res result_type; };
 
   /// Retrieve the result type for a function pointer.
@@ -156,7 +157,7 @@  _GLIBCXX_MEM_FN_TRAITS(&& noexcept, fals
   /// Retrieve the result type for a varargs function pointer.
   template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
     struct
-    _Weak_result_type_impl<_Res(*)(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL>
+    _Weak_result_type_impl<_Res(*)(_ArgTypes..., ...) _GLIBCXX_NOEXCEPT_QUAL>
     { typedef _Res result_type; };
 
   // Let _Weak_result_type_impl perform the real work.
--- libstdc++-v3/include/tr1/type_traits.jj	2024-10-01 00:09:07.468746064 +0200
+++ libstdc++-v3/include/tr1/type_traits	2024-11-25 17:57:41.059474123 +0100
@@ -235,25 +235,24 @@  namespace tr1
     struct is_function<_Res(_ArgTypes...)>
     : public true_type { };
   template<typename _Res, typename... _ArgTypes>
-    struct is_function<_Res(_ArgTypes......)>
-    : public true_type { };
+    struct is_function<_Res(_ArgTypes..., ...)> : public true_type { };
   template<typename _Res, typename... _ArgTypes>
     struct is_function<_Res(_ArgTypes...) const>
     : public true_type { };
   template<typename _Res, typename... _ArgTypes>
-    struct is_function<_Res(_ArgTypes......) const>
+    struct is_function<_Res(_ArgTypes..., ...) const>
     : public true_type { };
   template<typename _Res, typename... _ArgTypes>
     struct is_function<_Res(_ArgTypes...) volatile>
     : public true_type { };
   template<typename _Res, typename... _ArgTypes>
-    struct is_function<_Res(_ArgTypes......) volatile>
+    struct is_function<_Res(_ArgTypes..., ...) volatile>
     : public true_type { };
   template<typename _Res, typename... _ArgTypes>
     struct is_function<_Res(_ArgTypes...) const volatile>
     : public true_type { };
   template<typename _Res, typename... _ArgTypes>
-    struct is_function<_Res(_ArgTypes......) const volatile>
+    struct is_function<_Res(_ArgTypes..., ...) const volatile>
     : public true_type { };
 
   // composite type traits [4.5.2].