https://gcc.gnu.org/g:cc67d95dc100706ea665e8cce581d59466aba62e
commit r15-5813-gcc67d95dc100706ea665e8cce581d59466aba62e Author: Jakub Jelinek <ja...@redhat.com> Date: Sat Nov 30 01:49:21 2024 +0100 c++: Implement C++26 P3176R1 - The Oxford variadic comma While we are already in stage3, I wonder if implementing this small paper wouldn't be useful even for GCC 15, so that we have in the GCC world one extra year of deprecation of variadic ellipsis without preceding comma. The paper just deprecates something, I'd hope most of the C++ code in the wild when it uses variadic functions at all uses the comma before the ellipsis. 2024-11-30 Jakub Jelinek <ja...@redhat.com> gcc/c-family/ * c.opt (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: Implement C++26 P3176R1 - The Oxford variadic comma. (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. Diff: --- gcc/c-family/c-opts.cc | 5 +++++ gcc/c-family/c.opt | 4 ++++ gcc/c-family/c.opt.urls | 3 +++ gcc/cp/parser.cc | 10 ++++++++++ gcc/doc/invoke.texi | 21 +++++++++++++++++++-- gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C | 2 +- gcc/testsuite/g++.dg/cpp0x/gen-attrs-33.C | 2 +- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C | 2 +- gcc/testsuite/g++.dg/cpp0x/udlit-args-neg.C | 1 + gcc/testsuite/g++.dg/cpp0x/variadic164.C | 2 +- gcc/testsuite/g++.dg/cpp0x/variadic17.C | 6 +++--- gcc/testsuite/g++.dg/cpp0x/variadic28.C | 8 ++++---- gcc/testsuite/g++.dg/cpp0x/vt-65790.C | 2 +- .../g++.dg/cpp1y/lambda-generic-variadic19.C | 2 +- gcc/testsuite/g++.dg/cpp1z/fold10.C | 2 +- .../g++.dg/cpp23/explicit-obj-diagnostics3.C | 20 ++++++++++---------- gcc/testsuite/g++.dg/cpp26/variadic-comma1.C | 18 ++++++++++++++++++ gcc/testsuite/g++.dg/cpp26/variadic-comma2.C | 19 +++++++++++++++++++ gcc/testsuite/g++.dg/cpp26/variadic-comma3.C | 5 +++++ gcc/testsuite/g++.dg/cpp26/variadic-comma4.C | 5 +++++ gcc/testsuite/g++.dg/cpp26/variadic-comma5.C | 19 +++++++++++++++++++ gcc/testsuite/g++.dg/cpp2a/lambda-generic10.C | 2 +- gcc/testsuite/g++.dg/ext/attrib33.C | 2 +- gcc/testsuite/g++.old-deja/g++.law/operators15.C | 2 +- gcc/testsuite/g++.old-deja/g++.mike/p12306.C | 2 +- gcc/testsuite/g++.old-deja/g++.mike/p811.C | 4 ++-- libstdc++-v3/include/bits/refwrap.h | 7 ++++--- libstdc++-v3/include/std/functional | 2 +- libstdc++-v3/include/tr1/type_traits | 9 ++++----- 29 files changed, 147 insertions(+), 41 deletions(-) diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index 0871eb303726..7d139a7adf31 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -1061,6 +1061,11 @@ c_common_post_options (const char **pfilename) warn_array_compare, warn_array_compare || deprecated_in (cxx20)); + /* -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, diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 467d361bb3a7..0d255561b1bd 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -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. diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls index 56c814e1b5ca..8fbe3bd26989 100644 --- a/gcc/c-family/c.opt.urls +++ b/gcc/c-family/c.opt.urls @@ -310,6 +310,9 @@ UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wdeprecated-literal-operato 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) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index f519ab014640..94069d7a1fe9 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -25770,6 +25770,16 @@ cp_parser_parameter_declaration_clause (cp_parser* parser, 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. */ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 18a5754a0973..fa2532f437b6 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -4069,6 +4069,22 @@ string operator "" _i18n(const char*, std::size_t); // deprecated 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 @@ -10348,8 +10364,9 @@ In C++, explicitly specifying @option{-Wdeprecated} also enables 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 diff --git a/gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C b/gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C index eb5e23c82cf1..318e1486e8e2 100644 --- a/gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C +++ b/gcc/testsuite/g++.dg/analyzer/fd-bind-pr107783.C @@ -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); } diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-33.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-33.C index efb2a1ad6d06..485d349ecfce 100644 --- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-33.C +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-33.C @@ -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>; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C index a1ffaddc4a7a..1767dd711708 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C @@ -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]; diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-args-neg.C b/gcc/testsuite/g++.dg/cpp0x/udlit-args-neg.C index 72cb4b4c4cba..27508882f859 100644 --- a/gcc/testsuite/g++.dg/cpp0x/udlit-args-neg.C +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-args-neg.C @@ -27,6 +27,7 @@ operator ""_Foo(const char16_t *); // { dg-error "1:.Foo operator\"\"_Foo\\(cons 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" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic164.C b/gcc/testsuite/g++.dg/cpp0x/variadic164.C index 8f9cdb18c2d8..a3855346f5cc 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic164.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic164.C @@ -8,5 +8,5 @@ template <typename Tuple, typename... Tuples, int... ElementIndices, 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" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic17.C b/gcc/testsuite/g++.dg/cpp0x/variadic17.C index d54022a7c7b2..4791bb4e0fc0 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic17.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic17.C @@ -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 } } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic28.C b/gcc/testsuite/g++.dg/cpp0x/variadic28.C index b0278613cbff..57f6d23b21e7 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic28.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic28.C @@ -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 } } diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-65790.C b/gcc/testsuite/g++.dg/cpp0x/vt-65790.C index 477e9884304d..4e899630d63b 100644 --- a/gcc/testsuite/g++.dg/cpp0x/vt-65790.C +++ b/gcc/testsuite/g++.dg/cpp0x/vt-65790.C @@ -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 { diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic19.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic19.C index e78677de0b52..0fb873dd4f25 100644 --- a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic19.C +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic19.C @@ -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 } } diff --git a/gcc/testsuite/g++.dg/cpp1z/fold10.C b/gcc/testsuite/g++.dg/cpp1z/fold10.C index 1bd39a054000..87aee5b50f2f 100644 --- a/gcc/testsuite/g++.dg/cpp1z/fold10.C +++ b/gcc/testsuite/g++.dg/cpp1z/fold10.C @@ -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> diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C index f6a892eb0691..4ff13af29239 100644 --- a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C @@ -24,7 +24,7 @@ void S::f12(this S s = {}) {} // { dg-error "an explicit object parameter may no 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" } diff --git a/gcc/testsuite/g++.dg/cpp26/variadic-comma1.C b/gcc/testsuite/g++.dg/cpp26/variadic-comma1.C new file mode 100644 index 000000000000..d5cf13fe3729 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/variadic-comma1.C @@ -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 } } +{ +} diff --git a/gcc/testsuite/g++.dg/cpp26/variadic-comma2.C b/gcc/testsuite/g++.dg/cpp26/variadic-comma2.C new file mode 100644 index 000000000000..8d2e8f01bf25 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/variadic-comma2.C @@ -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" } +{ +} diff --git a/gcc/testsuite/g++.dg/cpp26/variadic-comma3.C b/gcc/testsuite/g++.dg/cpp26/variadic-comma3.C new file mode 100644 index 000000000000..6413478daac7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/variadic-comma3.C @@ -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" diff --git a/gcc/testsuite/g++.dg/cpp26/variadic-comma4.C b/gcc/testsuite/g++.dg/cpp26/variadic-comma4.C new file mode 100644 index 000000000000..12f0d545c846 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/variadic-comma4.C @@ -0,0 +1,5 @@ +// P3176R1 - The Oxford variadic comma +// { dg-do compile { target c++11 } } +// { dg-additional-options "-Wno-deprecated" } + +#include "variadic-comma1.C" diff --git a/gcc/testsuite/g++.dg/cpp26/variadic-comma5.C b/gcc/testsuite/g++.dg/cpp26/variadic-comma5.C new file mode 100644 index 000000000000..ccf3ebcab1e0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/variadic-comma5.C @@ -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" } +{ +} diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-generic10.C b/gcc/testsuite/g++.dg/cpp2a/lambda-generic10.C index 47a87bbfbd75..7329fa8e0905 100644 --- a/gcc/testsuite/g++.dg/cpp2a/lambda-generic10.C +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-generic10.C @@ -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 '\)'} } diff --git a/gcc/testsuite/g++.dg/ext/attrib33.C b/gcc/testsuite/g++.dg/ext/attrib33.C index 55bfc4cadb86..a244c1a1b99e 100644 --- a/gcc/testsuite/g++.dg/ext/attrib33.C +++ b/gcc/testsuite/g++.dg/ext/attrib33.C @@ -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>; diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators15.C b/gcc/testsuite/g++.old-deja/g++.law/operators15.C index ea0e68857131..9318f158c3d9 100644 --- a/gcc/testsuite/g++.old-deja/g++.law/operators15.C +++ b/gcc/testsuite/g++.old-deja/g++.law/operators15.C @@ -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; diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p12306.C b/gcc/testsuite/g++.old-deja/g++.mike/p12306.C index 6309016a308d..b96be33272d3 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p12306.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p12306.C @@ -4,7 +4,7 @@ void *ptr1, *ptr2; int fail = 0; -extern "C" int printf(const char *...); +extern "C" int printf(const char *, ...); class RWSlist { }; diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p811.C b/gcc/testsuite/g++.old-deja/g++.mike/p811.C index 174b16e1eee6..ee207151a29b 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p811.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p811.C @@ -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); } diff --git a/libstdc++-v3/include/bits/refwrap.h b/libstdc++-v3/include/bits/refwrap.h index a73cdc9c71ef..00a0b644331c 100644 --- a/libstdc++-v3/include/bits/refwrap.h +++ b/libstdc++-v3/include/bits/refwrap.h @@ -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, false_type, true_type) /// 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, false_type, true_type) /// 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. diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 743defc3cb86..a39124df1474 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -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"); diff --git a/libstdc++-v3/include/tr1/type_traits b/libstdc++-v3/include/tr1/type_traits index 5e55802fba71..22e156ab2985 100644 --- a/libstdc++-v3/include/tr1/type_traits +++ b/libstdc++-v3/include/tr1/type_traits @@ -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].