https://gcc.gnu.org/g:0cf68222d2df3af7fefad28a82fcd51d8b40a192

commit r15-1190-g0cf68222d2df3af7fefad28a82fcd51d8b40a192
Author: Joseph Myers <josmy...@redhat.com>
Date:   Tue Jun 11 23:00:04 2024 +0000

    c: Add -std=c2y, -std=gnu2y, -Wc23-c2y-compat, C2Y _Generic with type 
operand
    
    The first new C2Y feature, _Generic where the controlling operand is a
    type name rather than an expression (as defined in N3260), was voted
    into C2Y today.  (In particular, this form of _Generic allows
    distinguishing qualified and unqualified versions of a type.)  This
    feature also includes allowing the generic associations to specify
    incomplete and function types.
    
    Add this feature to GCC, along with the -std=c2y, -std=gnu2y and
    -Wc23-c2y-compat options to control when and how it is diagnosed.  As
    usual, the feature is allowed by default in older standards modes,
    subject to diagnosis with -pedantic, -pedantic-errors or
    -Wc23-c2y-compat.
    
    Bootstrapped with no regressions on x86_64-pc-linux-gnu.
    
    gcc/
            * doc/cpp.texi (__STDC_VERSION__): Document C2Y handling.
            * doc/invoke.texi (-Wc23-c2y-compat, -std=c2y, -std=gnu2y):
            Document options.
            (-std=gnu23): Update documentation.
            * doc/standards.texi (C Language): Document C2Y.  Update C23
            description.
            * config/rl78/rl78.cc (rl78_option_override): Handle "GNU C2Y"
            language name.
            * dwarf2out.cc (highest_c_language, gen_compile_unit_die):
            Likewise.
    
    gcc/c-family/
            * c-common.cc (flag_isoc2y): New.
            (flag_isoc99, flag_isoc11, flag_isoc23): Update comments.
            * c-common.h (flag_isoc2y): New.
            (clk_c, flag_isoc23): Update comments.
            * c-opts.cc (set_std_c2y): New.
            (c_common_handle_option): Handle OPT_std_c2y and OPT_std_gnu2y.
            (set_std_c89, set_std_c99, set_std_c11, set_std_c17, set_std_c23):
            Set flag_isoc2y.
            (set_std_c23): Update comment.
            * c.opt (Wc23-c2y-compat, std=c2y, std=gnu2y): New.
            * c.opt.urls: Regenerate.
    
    gcc/c/
            * c-errors.cc (pedwarn_c23): New.
            * c-parser.cc (disable_extension_diagnostics)
            (restore_extension_diagnostics): Save and restore
            warn_c23_c2y_compat.
            (c_parser_generic_selection): Handle type name as controlling
            operand.  Allow incomplete and function types subject to
            pedwarn_c23 calls.
            * c-tree.h (pedwarn_c23): New.
    
    gcc/testsuite/
            * gcc.dg/c23-generic-1.c, gcc.dg/c23-generic-2.c,
            gcc.dg/c23-generic-3.c, gcc.dg/c23-generic-4.c,
            gcc.dg/c2y-generic-1.c, gcc.dg/c2y-generic-2.c,
            gcc.dg/c2y-generic-3.c, gcc.dg/gnu2y-generic-1.c: New tests.
            * gcc.dg/c23-tag-6.c: Use -pedantic-errors.
    
    libcpp/
            * include/cpplib.h (CLK_GNUC2Y, CLK_STDC2Y): New.
            * init.cc (lang_defaults): Add GNUC2Y and STDC2Y entries.
            (cpp_init_builtins): Define __STDC_VERSION__ to 202500L for GNUC2Y
            and STDC2Y.

Diff:
---
 gcc/c-family/c-common.cc               | 10 +++--
 gcc/c-family/c-common.h                |  8 +++-
 gcc/c-family/c-opts.cc                 | 34 +++++++++++++-
 gcc/c-family/c.opt                     | 12 +++++
 gcc/c-family/c.opt.urls                |  3 ++
 gcc/c/c-errors.cc                      | 39 ++++++++++++++++
 gcc/c/c-parser.cc                      | 82 ++++++++++++++++++++++------------
 gcc/c/c-tree.h                         |  2 +
 gcc/config/rl78/rl78.cc                |  1 +
 gcc/doc/cpp.texi                       |  4 +-
 gcc/doc/invoke.texi                    | 23 +++++++++-
 gcc/doc/standards.texi                 |  8 +++-
 gcc/dwarf2out.cc                       |  5 ++-
 gcc/testsuite/gcc.dg/c23-generic-1.c   | 17 +++++++
 gcc/testsuite/gcc.dg/c23-generic-2.c   | 17 +++++++
 gcc/testsuite/gcc.dg/c23-generic-3.c   | 16 +++++++
 gcc/testsuite/gcc.dg/c23-generic-4.c   | 16 +++++++
 gcc/testsuite/gcc.dg/c23-tag-6.c       |  2 +-
 gcc/testsuite/gcc.dg/c2y-generic-1.c   | 15 +++++++
 gcc/testsuite/gcc.dg/c2y-generic-2.c   | 17 +++++++
 gcc/testsuite/gcc.dg/c2y-generic-3.c   |  9 ++++
 gcc/testsuite/gcc.dg/gnu2y-generic-1.c | 15 +++++++
 libcpp/include/cpplib.h                |  3 +-
 libcpp/init.cc                         |  5 +++
 24 files changed, 323 insertions(+), 40 deletions(-)

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 0341c44a2cd9..24335deeb582 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -216,18 +216,22 @@ int flag_cond_mismatch;
 
 int flag_isoc94;
 
-/* Nonzero means use the ISO C99 (or C11) dialect of C.  */
+/* Nonzero means use the ISO C99 (or later) dialect of C.  */
 
 int flag_isoc99;
 
-/* Nonzero means use the ISO C11 dialect of C.  */
+/* Nonzero means use the ISO C11 (or later) dialect of C.  */
 
 int flag_isoc11;
 
-/* Nonzero means use the ISO C23 dialect of C.  */
+/* Nonzero means use the ISO C23 (or later) dialect of C.  */
 
 int flag_isoc23;
 
+/* Nonzero means use the ISO C2Y (or later) dialect of C.  */
+
+int flag_isoc2y;
+
 /* Nonzero means that we have builtin functions, and main is an int.  */
 
 int flag_hosted = 1;
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index ae79912c89f6..48c89b603bcd 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -531,7 +531,7 @@ extern GTY(()) tree c_global_trees[CTI_MAX];
 
 enum c_language_kind
 {
-  clk_c                = 0,            /* C90, C94, C99, C11 or C23 */
+  clk_c                = 0,            /* C without ObjC features.  */
   clk_objc     = 1,            /* clk_c with ObjC features.  */
   clk_cxx      = 2,            /* ANSI/ISO C++ */
   clk_objcxx   = 3             /* clk_cxx with ObjC features.  */
@@ -676,10 +676,14 @@ extern int flag_isoc99;
 
 extern int flag_isoc11;
 
-/* Nonzero means use the ISO C23 dialect of C.  */
+/* Nonzero means use the ISO C23 (or later) dialect of C.  */
 
 extern int flag_isoc23;
 
+/* Nonzero means use the ISO C2Y (or later) dialect of C.  */
+
+extern int flag_isoc2y;
+
 /* Nonzero means that we have builtin functions, and main is an int.  */
 
 extern int flag_hosted;
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index be3058dca637..faaf9ee63509 100644
--- a/gcc/c-family/c-opts.cc
+++ b/gcc/c-family/c-opts.cc
@@ -121,6 +121,7 @@ static void set_std_c99 (int);
 static void set_std_c11 (int);
 static void set_std_c17 (int);
 static void set_std_c23 (int);
+static void set_std_c2y (int);
 static void check_deps_environment_vars (void);
 static void handle_deferred_opts (void);
 static void sanitize_cpp_opts (void);
@@ -743,6 +744,16 @@ c_common_handle_option (size_t scode, const char *arg, 
HOST_WIDE_INT value,
        set_std_c23 (false /* ISO */);
       break;
 
+    case OPT_std_c2y:
+      if (!preprocessing_asm_p)
+       set_std_c2y (true /* ISO */);
+      break;
+
+    case OPT_std_gnu2y:
+      if (!preprocessing_asm_p)
+       set_std_c2y (false /* ISO */);
+      break;
+
     case OPT_trigraphs:
       cpp_opts->trigraphs = 1;
       break;
@@ -1782,6 +1793,7 @@ set_std_c89 (int c94, int iso)
   flag_isoc99 = 0;
   flag_isoc11 = 0;
   flag_isoc23 = 0;
+  flag_isoc2y = 0;
   lang_hooks.name = "GNU C89";
 }
 
@@ -1793,6 +1805,7 @@ set_std_c99 (int iso)
   flag_no_asm = iso;
   flag_no_nonansi_builtin = iso;
   flag_iso = iso;
+  flag_isoc2y = 0;
   flag_isoc23 = 0;
   flag_isoc11 = 0;
   flag_isoc99 = 1;
@@ -1808,6 +1821,7 @@ set_std_c11 (int iso)
   flag_no_asm = iso;
   flag_no_nonansi_builtin = iso;
   flag_iso = iso;
+  flag_isoc2y = 0;
   flag_isoc23 = 0;
   flag_isoc11 = 1;
   flag_isoc99 = 1;
@@ -1823,6 +1837,7 @@ set_std_c17 (int iso)
   flag_no_asm = iso;
   flag_no_nonansi_builtin = iso;
   flag_iso = iso;
+  flag_isoc2y = 0;
   flag_isoc23 = 0;
   flag_isoc11 = 1;
   flag_isoc99 = 1;
@@ -1830,7 +1845,7 @@ set_std_c17 (int iso)
   lang_hooks.name = "GNU C17";
 }
 
-/* Set the C 2X standard (without GNU extensions if ISO).  */
+/* Set the C 23 standard (without GNU extensions if ISO).  */
 static void
 set_std_c23 (int iso)
 {
@@ -1838,6 +1853,7 @@ set_std_c23 (int iso)
   flag_no_asm = iso;
   flag_no_nonansi_builtin = iso;
   flag_iso = iso;
+  flag_isoc2y = 0;
   flag_isoc23 = 1;
   flag_isoc11 = 1;
   flag_isoc99 = 1;
@@ -1845,6 +1861,22 @@ set_std_c23 (int iso)
   lang_hooks.name = "GNU C23";
 }
 
+/* Set the C 2Y standard (without GNU extensions if ISO).  */
+static void
+set_std_c2y (int iso)
+{
+  cpp_set_lang (parse_in, iso ? CLK_STDC23: CLK_GNUC23);
+  flag_no_asm = iso;
+  flag_no_nonansi_builtin = iso;
+  flag_iso = iso;
+  flag_isoc2y = 1;
+  flag_isoc23 = 1;
+  flag_isoc11 = 1;
+  flag_isoc99 = 1;
+  flag_isoc94 = 1;
+  lang_hooks.name = "GNU C2Y";
+}
+
 
 /* Set the C++ 98 standard (without GNU extensions if ISO).  */
 static void
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index fb34c3b70319..b067369fa7ea 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -441,6 +441,10 @@ Wc11-c2x-compat
 C ObjC Alias(Wc11-c23-compat)
 Deprecated in favor of -Wc11-c23-compat.
 
+Wc23-c2y-compat
+C ObjC Var(warn_c23_c2y_compat) Init(-1) Warning
+Warn about features not present in ISO C23, but present in ISO C2Y.
+
 Wc90-c99-compat
 C ObjC CPP(cpp_warn_c90_c99_compat) CppReason(CPP_W_C90_C99_COMPAT) 
Var(warn_c90_c99_compat) Init(-1) Warning
 Warn about features not present in ISO C90, but present in ISO C99.
@@ -2515,6 +2519,10 @@ std=c2x
 C ObjC Alias(std=c23)
 Deprecated in favor of -std=c23.
 
+std=c2y
+C ObjC
+Conform to the ISO 202Y C standard draft (experimental and incomplete support).
+
 std=c89
 C ObjC Alias(std=c90)
 Conform to the ISO 1990 C standard.
@@ -2613,6 +2621,10 @@ std=gnu2x
 C ObjC Alias(std=gnu23)
 Deprecated in favor of -std=gnu23.
 
+std=gnu2y
+C ObjC
+Conform to the ISO 202Y C standard draft with GNU extensions (experimental and 
incomplete support).
+
 std=gnu89
 C ObjC Alias(std=gnu90)
 Conform to the ISO 1990 C standard with GNU extensions.
diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls
index dd455d7c0dc7..31d9ffef578f 100644
--- a/gcc/c-family/c.opt.urls
+++ b/gcc/c-family/c.opt.urls
@@ -160,6 +160,9 @@ 
UrlSuffix(gcc/Warning-Options.html#index-Wbuiltin-macro-redefined)
 Wc11-c23-compat
 UrlSuffix(gcc/Warning-Options.html#index-Wc11-c23-compat)
 
+Wc23-c2y-compat
+UrlSuffix(gcc/Warning-Options.html#index-Wc23-c2y-compat)
+
 Wc90-c99-compat
 UrlSuffix(gcc/Warning-Options.html#index-Wc90-c99-compat)
 
diff --git a/gcc/c/c-errors.cc b/gcc/c/c-errors.cc
index 7aa5e0db34e3..f36e7f9780a3 100644
--- a/gcc/c/c-errors.cc
+++ b/gcc/c/c-errors.cc
@@ -25,6 +25,45 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-tree.h"
 #include "opts.h"
 
+/* Issue an ISO C23 pedantic warning MSGID if -pedantic outside C2Y mode,
+   otherwise issue warning MSGID if -Wc23-c2y-compat is specified.
+   This function is supposed to be used for matters that are allowed in
+   ISO C2Y but not supported in ISO C23, thus we explicitly don't pedwarn
+   when C2Y is specified.  */
+
+bool
+pedwarn_c23 (location_t location, int opt, const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+  bool warned = false;
+  rich_location richloc (line_table, location);
+
+  va_start (ap, gmsgid);
+  /* If desired, issue the C23/C2Y compat warning, which is more specific
+     than -pedantic.  */
+  if (warn_c23_c2y_compat > 0)
+    {
+      diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
+                          (pedantic && !flag_isoc2y)
+                          ? DK_PEDWARN : DK_WARNING);
+      diagnostic.option_index = OPT_Wc23_c2y_compat;
+      warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
+    }
+  /* -Wno-c23-c2y-compat suppresses even the pedwarns.  */
+  else if (warn_c23_c2y_compat == 0)
+    ;
+  /* For -pedantic outside C2Y, issue a pedwarn.  */
+  else if (pedantic && !flag_isoc2y)
+    {
+      diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
+      diagnostic.option_index = opt;
+      warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
+    }
+  va_end (ap);
+  return warned;
+}
+
 /* Issue an ISO C11 pedantic warning MSGID if -pedantic outside C23 mode,
    otherwise issue warning MSGID if -Wc11-c23-compat is specified.
    This function is supposed to be used for matters that are allowed in
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 0c5018134ccd..e83e9c683f75 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -1534,6 +1534,9 @@ disable_extension_diagnostics (void)
             /* Similarly for warn_c11_c23_compat.  */
             | ((warn_c11_c23_compat == 1) << 11)
             | ((warn_c11_c23_compat == -1) << 12)
+            /* Similarly for warn_c23_c2y_compat.  */
+            | ((warn_c23_c2y_compat == 1) << 13)
+            | ((warn_c23_c2y_compat == -1) << 14)
             );
   cpp_opts->cpp_pedantic = pedantic = 0;
   warn_pointer_arith = 0;
@@ -1545,6 +1548,7 @@ disable_extension_diagnostics (void)
   warn_c90_c99_compat = 0;
   warn_c99_c11_compat = 0;
   warn_c11_c23_compat = 0;
+  warn_c23_c2y_compat = 0;
   return ret;
 }
 
@@ -1565,6 +1569,7 @@ restore_extension_diagnostics (int flags)
   warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
   warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
   warn_c11_c23_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
+  warn_c23_c2y_compat = (flags >> 13) & 1 ? 1 : ((flags >> 14) & 1 ? -1 : 0);
 }
 
 /* Helper data structure for parsing #pragma acc routine.  */
@@ -10273,8 +10278,14 @@ struct c_generic_association
 /* Parse a generic-selection.  (C11 6.5.1.1).
    
    generic-selection:
-     _Generic ( assignment-expression , generic-assoc-list )
-     
+     _Generic ( generic-controlling-operand , generic-assoc-list )
+
+  generic-controlling-operand:
+    assignment-expression
+    type-name
+
+  (The use of a type-name is new in C2Y.)
+
    generic-assoc-list:
      generic-association
      generic-assoc-list , generic-association
@@ -10314,30 +10325,43 @@ c_parser_generic_selection (c_parser *parser)
   if (!parens.require_open (parser))
     return error_expr;
 
-  c_inhibit_evaluation_warnings++;
   selector_loc = c_parser_peek_token (parser)->location;
-  selector = c_parser_expr_no_commas (parser, NULL);
-  selector = default_function_array_conversion (selector_loc, selector);
-  c_inhibit_evaluation_warnings--;
-
-  if (selector.value == error_mark_node)
+  if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
     {
-      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
-      return selector;
-    }
-  mark_exp_read (selector.value);
-  selector_type = TREE_TYPE (selector.value);
-  /* In ISO C terms, rvalues (including the controlling expression of
-     _Generic) do not have qualified types.  */
-  if (TREE_CODE (selector_type) != ARRAY_TYPE)
-    selector_type = TYPE_MAIN_VARIANT (selector_type);
-  /* In ISO C terms, _Noreturn is not part of the type of expressions
-     such as &abort, but in GCC it is represented internally as a type
-     qualifier.  */
-  if (FUNCTION_POINTER_TYPE_P (selector_type)
-      && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
-    selector_type
-      = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
+      c_inhibit_evaluation_warnings++;
+      pedwarn_c23 (selector_loc, OPT_Wpedantic,
+                  "ISO C does not support use of type name as %<_Generic%> "
+                  "controlling operand before C2Y");
+      struct c_type_name *type = c_parser_type_name (parser);
+      selector_type = groktypename (type, NULL, NULL);
+      c_inhibit_evaluation_warnings--;
+    }
+  else
+    {
+      c_inhibit_evaluation_warnings++;
+      selector = c_parser_expr_no_commas (parser, NULL);
+      selector = default_function_array_conversion (selector_loc, selector);
+      c_inhibit_evaluation_warnings--;
+
+      if (selector.value == error_mark_node)
+       {
+         c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+         return selector;
+       }
+      mark_exp_read (selector.value);
+      selector_type = TREE_TYPE (selector.value);
+      /* In ISO C terms, rvalues (including the controlling expression
+        of _Generic) do not have qualified types.  */
+      if (TREE_CODE (selector_type) != ARRAY_TYPE)
+       selector_type = TYPE_MAIN_VARIANT (selector_type);
+      /* In ISO C terms, _Noreturn is not part of the type of expressions
+        such as &abort, but in GCC it is represented internally as a type
+        qualifier.  */
+      if (FUNCTION_POINTER_TYPE_P (selector_type)
+         && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
+       selector_type
+         = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
+    }
 
   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
     {
@@ -10376,11 +10400,13 @@ c_parser_generic_selection (c_parser *parser)
            }
 
          if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
-           error_at (assoc.type_location,
-                     "%<_Generic%> association has function type");
+           pedwarn_c23 (assoc.type_location, OPT_Wpedantic,
+                        "ISO C does not support %<_Generic%> association with "
+                        "function type before C2Y");
          else if (!COMPLETE_TYPE_P (assoc.type))
-           error_at (assoc.type_location,
-                     "%<_Generic%> association has incomplete type");
+           pedwarn_c23 (assoc.type_location, OPT_Wpedantic,
+                        "ISO C does not support %<_Generic%> association with "
+                        "incomplete type before C2Y");
 
          if (c_type_variably_modified_p (assoc.type))
            error_at (assoc.type_location,
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 56a33b8156c6..15da875a0290 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -905,6 +905,8 @@ extern bool pedwarn_c99 (location_t, int opt, const char *, 
...)
     ATTRIBUTE_GCC_DIAG(3,4);
 extern bool pedwarn_c11 (location_t, int opt, const char *, ...)
     ATTRIBUTE_GCC_DIAG(3,4);
+extern bool pedwarn_c23 (location_t, int opt, const char *, ...)
+    ATTRIBUTE_GCC_DIAG(3,4);
 
 extern void
 set_c_expr_source_range (c_expr *expr,
diff --git a/gcc/config/rl78/rl78.cc b/gcc/config/rl78/rl78.cc
index e5345bfa9dd9..b4bb145b5a69 100644
--- a/gcc/config/rl78/rl78.cc
+++ b/gcc/config/rl78/rl78.cc
@@ -367,6 +367,7 @@ rl78_option_override (void)
       && strcmp (lang_hooks.name, "GNU C11")
       && strcmp (lang_hooks.name, "GNU C17")
       && strcmp (lang_hooks.name, "GNU C23")
+      && strcmp (lang_hooks.name, "GNU C2Y")
       && strcmp (lang_hooks.name, "GNU C89")
       && strcmp (lang_hooks.name, "GNU C99")
       /* Compiling with -flto results in a language of GNU GIMPLE being 
used... */
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index 3f38ca37feaf..a99c8dfdbe33 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -1887,7 +1887,9 @@ signifies the 2011 revision of the C standard; the value
 @code{201710L} signifies the 2017 revision of the C standard (which is
 otherwise identical to the 2011 version apart from correction of
 defects).  The value @code{202311L} is used for the experimental
-@option{-std=c23} and @option{-std=gnu23} modes.
+@option{-std=c23} and @option{-std=gnu23} modes.  An unspecified value
+larger than @code{202311L} is used for the experimental
+@option{-std=c2y} and @option{-std=gnu2y} modes.
 
 This macro is not defined if the @option{-traditional-cpp} option is
 used, nor when compiling C++ or Objective-C@.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a0b375646468..26e6a349d51d 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -340,7 +340,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wbool-compare  -Wbool-operation
 -Wno-builtin-declaration-mismatch
 -Wno-builtin-macro-redefined  -Wc90-c99-compat  -Wc99-c11-compat
--Wc11-c23-compat
+-Wc11-c23-compat  -Wc23-c2y-compat
 -Wc++-compat  -Wc++11-compat  -Wc++14-compat  -Wc++17-compat
 -Wc++20-compat
 -Wno-c++11-extensions  -Wno-c++14-extensions -Wno-c++17-extensions
@@ -2472,6 +2472,10 @@ ISO C23, the 2023 revision of the ISO C standard 
(expected to be
 published in 2024).  The support for this version is experimental and
 incomplete.  The name @samp{c2x} is deprecated.
 
+@item c2y
+The next version of the ISO C standard, still under development.  The
+support for this version is experimental and incomplete.
+
 @item gnu90
 @itemx gnu89
 GNU dialect of ISO C90 (including some C99 features).
@@ -2491,6 +2495,10 @@ GNU dialect of ISO C17.  This is the default for C code.
 
 @item gnu23
 @itemx gnu2x
+GNU dialect of ISO C23.  The support for this version is experimental
+and incomplete.  The name @samp{gnu2x} is deprecated.
+
+@item gnu2y
 The next version of the ISO C standard, still under development, plus
 GNU extensions.  The support for this version is experimental and
 incomplete.  The name @samp{gnu2x} is deprecated.
@@ -9326,6 +9334,19 @@ deprecated.
 When not compiling in C23 mode, these warnings are upgraded to errors
 by @option{-pedantic-errors}.
 
+@opindex Wc23-c2y-compat
+@opindex Wno-c23-c2y-compat
+@item -Wc23-c2y-compat @r{(C and Objective-C only)}
+@itemx -Wc23-c2y-compat @r{(C and Objective-C only)}
+Warn about features not present in ISO C23, but present in ISO C2Y.
+For instance, warn about @code{_Generic} selecting with a type name
+instead of an expression.  This option is independent of the standards
+mode.  Warnings are disabled in the expression that follows
+@code{__extension__}.
+
+When not compiling in C2Y mode, these warnings are upgraded to errors
+by @option{-pedantic-errors}.
+
 @opindex Wc++-compat
 @opindex Wno-c++-compat
 @item -Wc++-compat @r{(C and Objective-C only)}
diff --git a/gcc/doc/standards.texi b/gcc/doc/standards.texi
index 586835b28f31..484fbb10352d 100644
--- a/gcc/doc/standards.texi
+++ b/gcc/doc/standards.texi
@@ -42,6 +42,8 @@ with some exceptions, and possibly with some extensions.
 @cindex C23
 @cindex ISO C2X
 @cindex C2X
+@cindex ISO C2Y
+@cindex C2Y
 @cindex Technical Corrigenda
 @cindex TC1
 @cindex Technical Corrigendum 1
@@ -113,12 +115,16 @@ known as @dfn{C17} and is supported with 
@option{-std=c17} or
 @option{-std=c11}, and the only difference between the options is the
 value of @code{__STDC_VERSION__}.
 
-A further version of the C standard, known as @dfn{C23}, is under
+A fifth version of the C standard, known as @dfn{C23}, is under
 development and expected to be published in 2024 as ISO/IEC 9899:2024.
 (While in development, drafts of this standard version were referred
 to as @dfn{C2X}.)  Experimental and incomplete support for this is
 enabled with @option{-std=c23} or @option{-std=iso9899:2024}.
 
+A further version of the C standard, known as @dfn{C2Y}, is under
+development; experimental and incomplete support for this is enabled
+with @option{-std=c2y}.
+
 By default, GCC provides some extensions to the C language that, on
 rare occasions conflict with the C standard.  @xref{C
 Extensions,,Extensions to the C Language Family}.  
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index f90f7b1cfef2..18256843a4c5 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -25281,6 +25281,8 @@ highest_c_language (const char *lang1, const char 
*lang2)
   if (strcmp ("GNU C++98", lang1) == 0 || strcmp ("GNU C++98", lang2) == 0)
     return "GNU C++98";
 
+  if (strcmp ("GNU C2Y", lang1) == 0 || strcmp ("GNU C2Y", lang2) == 0)
+    return "GNU C2Y";
   if (strcmp ("GNU C23", lang1) == 0 || strcmp ("GNU C23", lang2) == 0)
     return "GNU C23";
   if (strcmp ("GNU C17", lang1) == 0 || strcmp ("GNU C17", lang2) == 0)
@@ -25363,7 +25365,8 @@ gen_compile_unit_die (const char *filename)
          if (dwarf_version >= 5 /* || !dwarf_strict */)
            if (strcmp (language_string, "GNU C11") == 0
                || strcmp (language_string, "GNU C17") == 0
-               || strcmp (language_string, "GNU C23") == 0)
+               || strcmp (language_string, "GNU C23") == 0
+               || strcmp (language_string, "GNU C2Y") == 0)
              language = DW_LANG_C11;
        }
     }
diff --git a/gcc/testsuite/gcc.dg/c23-generic-1.c 
b/gcc/testsuite/gcc.dg/c23-generic-1.c
new file mode 100644
index 000000000000..26c97fb4a9ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-generic-1.c
@@ -0,0 +1,17 @@
+/* Test C2Y _Generic features: error with -std=c23 -pedantic-errors.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+_Static_assert (_Generic (const int, int : 1, const int : 2) == 2); /* { 
dg-error "use of type name" } */
+
+_Static_assert (_Generic (void, int : 1, void : 2) == 2); /* { dg-error "use 
of type name" } */
+/* { dg-error "incomplete type" "incomplete type" { target *-*-* } .-1 } */
+
+_Static_assert (_Generic (int (), int (*) () : 1, int () : 2) == 2); /* { 
dg-error "use of type name" } */
+/* { dg-error "function type" "function type" { target *-*-* } .-1 } */
+
+const int ci;
+
+_Static_assert (_Generic (typeof (ci), const int : 1, int : 2) == 1); /* { 
dg-error "use of type name" } */
+
+_Static_assert (_Generic (ci, const int : 1, int : 2) == 2);
diff --git a/gcc/testsuite/gcc.dg/c23-generic-2.c 
b/gcc/testsuite/gcc.dg/c23-generic-2.c
new file mode 100644
index 000000000000..eb31d37b092c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-generic-2.c
@@ -0,0 +1,17 @@
+/* Test C2Y _Generic features: warning with -std=c23 -pedantic.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic" } */
+
+_Static_assert (_Generic (const int, int : 1, const int : 2) == 2); /* { 
dg-warning "use of type name" } */
+
+_Static_assert (_Generic (void, int : 1, void : 2) == 2); /* { dg-warning "use 
of type name" } */
+/* { dg-warning "incomplete type" "incomplete type" { target *-*-* } .-1 } */
+
+_Static_assert (_Generic (int (), int (*) () : 1, int () : 2) == 2); /* { 
dg-warning "use of type name" } */
+/* { dg-warning "function type" "function type" { target *-*-* } .-1 } */
+
+const int ci;
+
+_Static_assert (_Generic (typeof (ci), const int : 1, int : 2) == 1); /* { 
dg-warning "use of type name" } */
+
+_Static_assert (_Generic (ci, const int : 1, int : 2) == 2);
diff --git a/gcc/testsuite/gcc.dg/c23-generic-3.c 
b/gcc/testsuite/gcc.dg/c23-generic-3.c
new file mode 100644
index 000000000000..adf4b3549fff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-generic-3.c
@@ -0,0 +1,16 @@
+/* Test C2Y _Generic features: no warning or error with -std=c23
+   -pedantic-errors -Wno-c23-c2y-compat.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors -Wno-c23-c2y-compat" } */
+
+_Static_assert (_Generic (const int, int : 1, const int : 2) == 2);
+
+_Static_assert (_Generic (void, int : 1, void : 2) == 2);
+
+_Static_assert (_Generic (int (), int (*) () : 1, int () : 2) == 2);
+
+const int ci;
+
+_Static_assert (_Generic (typeof (ci), const int : 1, int : 2) == 1);
+
+_Static_assert (_Generic (ci, const int : 1, int : 2) == 2);
diff --git a/gcc/testsuite/gcc.dg/c23-generic-4.c 
b/gcc/testsuite/gcc.dg/c23-generic-4.c
new file mode 100644
index 000000000000..f9f65615dd98
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-generic-4.c
@@ -0,0 +1,16 @@
+/* Test C2Y _Generic features: no warning or error with -std=c23 by
+   default.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23" } */
+
+_Static_assert (_Generic (const int, int : 1, const int : 2) == 2);
+
+_Static_assert (_Generic (void, int : 1, void : 2) == 2);
+
+_Static_assert (_Generic (int (), int (*) () : 1, int () : 2) == 2);
+
+const int ci;
+
+_Static_assert (_Generic (typeof (ci), const int : 1, int : 2) == 1);
+
+_Static_assert (_Generic (ci, const int : 1, int : 2) == 2);
diff --git a/gcc/testsuite/gcc.dg/c23-tag-6.c b/gcc/testsuite/gcc.dg/c23-tag-6.c
index 1b65ed3e35d4..7a81487c6e44 100644
--- a/gcc/testsuite/gcc.dg/c23-tag-6.c
+++ b/gcc/testsuite/gcc.dg/c23-tag-6.c
@@ -1,6 +1,6 @@
 /*
  * { dg-do compile }
- * { dg-options "-std=c23" }
+ * { dg-options "-std=c23 -pedantic-errors" }
  */
 
 // (in-)completeness
diff --git a/gcc/testsuite/gcc.dg/c2y-generic-1.c 
b/gcc/testsuite/gcc.dg/c2y-generic-1.c
new file mode 100644
index 000000000000..afb46df99fe4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2y-generic-1.c
@@ -0,0 +1,15 @@
+/* Test C2Y _Generic features.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+_Static_assert (_Generic (const int, int : 1, const int : 2) == 2);
+
+_Static_assert (_Generic (void, int : 1, void : 2) == 2);
+
+_Static_assert (_Generic (int (), int (*) () : 1, int () : 2) == 2);
+
+const int ci;
+
+_Static_assert (_Generic (typeof (ci), const int : 1, int : 2) == 1);
+
+_Static_assert (_Generic (ci, const int : 1, int : 2) == 2);
diff --git a/gcc/testsuite/gcc.dg/c2y-generic-2.c 
b/gcc/testsuite/gcc.dg/c2y-generic-2.c
new file mode 100644
index 000000000000..c37fcc1283b9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2y-generic-2.c
@@ -0,0 +1,17 @@
+/* Test C2Y _Generic features: warning with -Wc23-c2y-compat.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors -Wc23-c2y-compat" } */
+
+_Static_assert (_Generic (const int, int : 1, const int : 2) == 2); /* { 
dg-warning "use of type name" } */
+
+_Static_assert (_Generic (void, int : 1, void : 2) == 2); /* { dg-warning "use 
of type name" } */
+/* { dg-warning "incomplete type" "incomplete type" { target *-*-* } .-1 } */
+
+_Static_assert (_Generic (int (), int (*) () : 1, int () : 2) == 2); /* { 
dg-warning "use of type name" } */
+/* { dg-warning "function type" "function type" { target *-*-* } .-1 } */
+
+const int ci;
+
+_Static_assert (_Generic (typeof (ci), const int : 1, int : 2) == 1); /* { 
dg-warning "use of type name" } */
+
+_Static_assert (_Generic (ci, const int : 1, int : 2) == 2);
diff --git a/gcc/testsuite/gcc.dg/c2y-generic-3.c 
b/gcc/testsuite/gcc.dg/c2y-generic-3.c
new file mode 100644
index 000000000000..09174fdb095d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2y-generic-3.c
@@ -0,0 +1,9 @@
+/* Test C2Y _Generic features: VM types still not allowed.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+void
+f (int i)
+{
+  (void) _Generic (i, int : 1, int (*)[i] : 2); /* { dg-error "variable 
length" } */
+}
diff --git a/gcc/testsuite/gcc.dg/gnu2y-generic-1.c 
b/gcc/testsuite/gcc.dg/gnu2y-generic-1.c
new file mode 100644
index 000000000000..98868ad51d1c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu2y-generic-1.c
@@ -0,0 +1,15 @@
+/* Test C2Y _Generic features: __extension__ suppresses -Wc23-c2y-compat
+   warnings (and the state is restored after __extension__).  */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu2y -pedantic-errors -Wc23-c2y-compat" } */
+
+_Static_assert (__extension__ _Generic (const int, int : 1, const int : 2) == 
2);
+_Static_assert (_Generic (const int, int : 1, const int : 2) == 2); /* { 
dg-warning "use of type name" } */
+
+_Static_assert (__extension__ _Generic (void, int : 1, void : 2) == 2);
+_Static_assert (_Generic (void, int : 1, void : 2) == 2); /* { dg-warning "use 
of type name" } */
+/* { dg-warning "incomplete type" "incomplete type" { target *-*-* } .-1 } */
+
+_Static_assert (__extension__ _Generic (int (), int (*) () : 1, int () : 2) == 
2);
+_Static_assert (_Generic (int (), int (*) () : 1, int () : 2) == 2); /* { 
dg-warning "use of type name" } */
+/* { dg-warning "function type" "function type" { target *-*-* } .-1 } */
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index c62374d31929..d76817c94fc4 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -172,8 +172,9 @@ enum cpp_ttype
 
 /* C language kind, used when calling cpp_create_reader.  */
 enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_GNUC11, CLK_GNUC17, CLK_GNUC23,
+            CLK_GNUC2Y,
             CLK_STDC89, CLK_STDC94, CLK_STDC99, CLK_STDC11, CLK_STDC17,
-            CLK_STDC23,
+            CLK_STDC23, CLK_STDC2Y,
             CLK_GNUCXX, CLK_CXX98, CLK_GNUCXX11, CLK_CXX11,
             CLK_GNUCXX14, CLK_CXX14, CLK_GNUCXX17, CLK_CXX17,
             CLK_GNUCXX20, CLK_CXX20, CLK_GNUCXX23, CLK_CXX23,
diff --git a/libcpp/init.cc b/libcpp/init.cc
index c457fa659e7b..9ae06a9595d9 100644
--- a/libcpp/init.cc
+++ b/libcpp/init.cc
@@ -109,12 +109,14 @@ static const struct lang_flags lang_defaults[] =
   /* GNUC11   */  { 1,  0,  1,  1,  1,  0,    0,  1,   1,   1,   0,    0,     
0,     0,   0,      1,   1,     0,   0,   0,      0,      0,    0 },
   /* GNUC17   */  { 1,  0,  1,  1,  1,  0,    0,  1,   1,   1,   0,    0,     
0,     0,   0,      1,   1,     0,   0,   0,      0,      0,    0 },
   /* GNUC23   */  { 1,  0,  1,  1,  1,  1,    0,  1,   1,   1,   0,    1,     
1,     0,   1,      1,   1,     1,   0,   1,      1,      0,    1 },
+  /* GNUC2Y   */  { 1,  0,  1,  1,  1,  1,    0,  1,   1,   1,   0,    1,     
1,     0,   1,      1,   1,     1,   0,   1,      1,      0,    1 },
   /* STDC89   */  { 0,  0,  0,  0,  0,  0,    1,  0,   0,   0,   0,    0,     
0,     1,   0,      0,   0,     0,   0,   0,      0,      0,    0 },
   /* STDC94   */  { 0,  0,  0,  0,  0,  0,    1,  1,   0,   0,   0,    0,     
0,     1,   0,      0,   0,     0,   0,   0,      0,      0,    0 },
   /* STDC99   */  { 1,  0,  1,  1,  0,  0,    1,  1,   0,   0,   0,    0,     
0,     1,   0,      0,   0,     0,   0,   0,      0,      0,    0 },
   /* STDC11   */  { 1,  0,  1,  1,  1,  0,    1,  1,   1,   0,   0,    0,     
0,     1,   0,      0,   0,     0,   0,   0,      0,      0,    0 },
   /* STDC17   */  { 1,  0,  1,  1,  1,  0,    1,  1,   1,   0,   0,    0,     
0,     1,   0,      0,   0,     0,   0,   0,      0,      0,    0 },
   /* STDC23   */  { 1,  0,  1,  1,  1,  1,    1,  1,   1,   0,   0,    1,     
1,     0,   1,      1,   1,     1,   0,   1,      1,      0,    1 },
+  /* STDC2Y   */  { 1,  0,  1,  1,  1,  1,    1,  1,   1,   0,   0,    1,     
1,     0,   1,      1,   1,     1,   0,   1,      1,      0,    1 },
   /* GNUCXX   */  { 0,  1,  1,  1,  0,  1,    0,  1,   0,   0,   0,    0,     
0,     0,   0,      1,   1,     0,   0,   0,      0,      0,    1 },
   /* CXX98    */  { 0,  1,  0,  1,  0,  1,    1,  1,   0,   0,   0,    0,     
0,     1,   0,      0,   1,     0,   0,   0,      0,      0,    1 },
   /* GNUCXX11 */  { 1,  1,  1,  1,  1,  1,    0,  1,   1,   1,   1,    0,     
0,     0,   0,      1,   1,     0,   0,   0,      0,      0,    1 },
@@ -595,6 +597,9 @@ cpp_init_builtins (cpp_reader *pfile, int hosted)
   else if (CPP_OPTION (pfile, lang) == CLK_STDC23
           || CPP_OPTION (pfile, lang) == CLK_GNUC23)
     _cpp_define_builtin (pfile, "__STDC_VERSION__ 202311L");
+  else if (CPP_OPTION (pfile, lang) == CLK_STDC2Y
+          || CPP_OPTION (pfile, lang) == CLK_GNUC2Y)
+    _cpp_define_builtin (pfile, "__STDC_VERSION__ 202500L");
   else if (CPP_OPTION (pfile, lang) == CLK_STDC17
           || CPP_OPTION (pfile, lang) == CLK_GNUC17)
     _cpp_define_builtin (pfile, "__STDC_VERSION__ 201710L");

Reply via email to