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,
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.
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)
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. */
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
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
_Bind(_Bind &);
};
template <typename _Func, typename _BoundArgs>
-_Bind bind(_Func, _BoundArgs &&...);
+_Bind bind(_Func, _BoundArgs &&, ...);
void test01() { bind(minus(), _2, _1); }
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>;
{
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];
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" }
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" }
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>
};
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 } }
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;
};
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 } }
// PR c++/65790
// { dg-do compile { target c++11 } }
-extern "C" int printf(const char* ...);
+extern "C" int printf(const char*, ...);
namespace std
{
// 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 } }
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>
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" }
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" }
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" }
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" }
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" }
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" }
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" }
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" }
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" }
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" }
--- /dev/null
+// 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 } }
+{
+}
--- /dev/null
+// 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" }
+{
+}
--- /dev/null
+// P3176R1 - The Oxford variadic comma
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-deprecated-variadic-comma-omission" }
+
+#include "variadic-comma1.C"
--- /dev/null
+// P3176R1 - The Oxford variadic comma
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-deprecated" }
+
+#include "variadic-comma1.C"
--- /dev/null
+// 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" }
+{
+}
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 '\)'} }
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>;
// 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;
void *ptr1, *ptr2;
int fail = 0;
-extern "C" int printf(const char *...);
+extern "C" int printf(const char *, ...);
class RWSlist { };
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);
};
{ 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); }
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; \
/// 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.
/// 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.
};
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");
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].