From patchwork Tue Jun 11 23:01:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 1946589 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=T5vpn+YP; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VzPN01QC2z20Pb for ; Wed, 12 Jun 2024 09:02:55 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 446403858D39 for ; Tue, 11 Jun 2024 23:02:54 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 74CFA3858D39 for ; Tue, 11 Jun 2024 23:02:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 74CFA3858D39 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 74CFA3858D39 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1718146955; cv=none; b=HU3GU6zpX6UijOdodpXxHRHXE5y4t+sOzF56mbEWekTCDTRrWfWwSAW5DLP9aQJMEFIkH6jwbTekrxj+K54P4nzbcaS1WRMJ52TOMcp1cTNwuXvZ3WNZfzemlAeq+21mDBb0e8NluLPhlZGyMOfly5KZT6XOORMQuLy716znUJ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1718146955; c=relaxed/simple; bh=TdiYrgfg8aWrb3nW4XjVn8UXY8ER28vEb36MU0hsm+I=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=xC41vKQwpNRsIwbcrbe2oEJrc9iE6S1jDgf7QDnj7d0wF1r/yI22Ktbd8WB9CvIuben3vsTJPAr5fQRPN/ELtH7h9zTE6lBqu0RMLm55Oq9caSSpzZy3IDgtEYQQQ6UNxNUAXEioahoooKUkHl8mKT5H6EgANBxzmuHhon6ZtlE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1718146951; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=uA4rHLbS+C28x38r8RkN/fC7/RYYQSFXV6celB1Lrq8=; b=T5vpn+YPQV2JGKmkQlEoc8sKUu/8V+1SFm7+9/deHbMWmR16hAIe92MY3xr+HmzmE6dxmQ 57CuQ/lAuhR1y1dW51jGrOBW0KnXAtWBrSbuiurKDTsqqqk4P8sLOh670KZz2kKVxmxuLk dSa3VsHAyHziA6Fz2xxAXJdcDgwfMg4= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-640-yaN9z8iDMXGiqvDr7Tfprg-1; Tue, 11 Jun 2024 19:02:29 -0400 X-MC-Unique: yaN9z8iDMXGiqvDr7Tfprg-1 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-421f43ddc2aso16773505e9.1 for ; Tue, 11 Jun 2024 16:02:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718146947; x=1718751747; h=mime-version:message-id:subject:to:from:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=uA4rHLbS+C28x38r8RkN/fC7/RYYQSFXV6celB1Lrq8=; b=o+9M9qvU9PWhgDt0iVNCsklDJ3JwLITvs8GKLGTCZ7+qCgjEpX3BC3ujyjkkv1E51R +OS5D4wFhOn7ocfWarApq7ULrfui7wM2yPDxgfBRzTCVXyYgsUnk5PpYbyXlnuGc1soF 9F24E6/1pMkATn4SZGC3VOCuwm0O6UPKxynTa0hkad/JY0gQznn9xxigNiphy9sqQV6P VTxSseSNxL+OvMpMvp0c6umqfAsHZEXn7frLYN9gwYhuj+ZyQZ7P+YqJTaroGP1X5uyY P+HjbdY40gzKIiksCPLrhAuCelMn6f8TNIyFdrM9bGArnU+YO8yyopejce6CsvSk5IrO 4OPQ== X-Gm-Message-State: AOJu0YzpPrGVUvlOFWnUKTH3tiDEXWk0FZdCZwC0JyeVhCFzaPXamKjH fQH4MyXlViFvr+wCt+2ZLM/K018WOzsik3pfCzbabLb4GXQB1IEefAVCoR2jOn7PRHkOjmvmPWo UTCXxO3bBzuEgtdWQT8GpZl45lX+mTBV5nnY3T+Jtl1Z1lfbEEpabzSUGpaYlukk7VkWVcmJp1r 6qu10e8V0Qx3FclSKZ5bjLTQn+Ivfap+uXUxdh+qw= X-Received: by 2002:a05:600c:4ecf:b0:421:7aad:370a with SMTP id 5b1f17b1804b1-422863adb55mr3195315e9.9.1718146946029; Tue, 11 Jun 2024 16:02:26 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE9d67zYvTjZpZ/w4ZAJmUX2ajJI+rRWsvALHdtIYInjKqLjstjr2S79SJR6IMHpqdNBOfNJg== X-Received: by 2002:a05:600c:4ecf:b0:421:7aad:370a with SMTP id 5b1f17b1804b1-422863adb55mr3195015e9.9.1718146944937; Tue, 11 Jun 2024 16:02:24 -0700 (PDT) Received: from digraph.polyomino.org.uk (digraph.polyomino.org.uk. [2001:8b0:bf73:93f7::51bb:e332]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42286fe9263sm2954895e9.15.2024.06.11.16.02.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Jun 2024 16:02:24 -0700 (PDT) Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.95) (envelope-from ) id 1sHAUz-00CG6c-EW for gcc-patches@gcc.gnu.org; Tue, 11 Jun 2024 23:01:53 +0000 Date: Tue, 11 Jun 2024 23:01:53 +0000 (UTC) From: Joseph Myers To: gcc-patches@gcc.gnu.org Subject: [committed] c: Add -std=c2y, -std=gnu2y, -Wc23-c2y-compat, C2Y _Generic with type operand Message-ID: <69a2bd1f-6877-6f5e-1940-3154f7471ba3@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SCC_10_SHORT_WORD_LINES, SCC_20_SHORT_WORD_LINES, SCC_5_SHORT_WORD_LINES, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org 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 --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index 0341c44a2cd..24335deeb58 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 ae79912c89f..48c89b603bc 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 be3058dca63..faaf9ee6350 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 fb34c3b7031..b067369fa7e 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 dd455d7c0dc..31d9ffef578 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 7aa5e0db34e..f36e7f9780a 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 0c5018134cc..e83e9c683f7 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 56a33b8156c..15da875a029 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 e5345bfa9dd..b4bb145b5a6 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 3f38ca37fea..a99c8dfdbe3 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 a0b37564646..26e6a349d51 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 586835b28f3..484fbb10352 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 f90f7b1cfef..18256843a4c 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 00000000000..26c97fb4a9e --- /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 00000000000..eb31d37b092 --- /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 00000000000..adf4b3549ff --- /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 00000000000..f9f65615dd9 --- /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 1b65ed3e35d..7a81487c6e4 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 00000000000..afb46df99fe --- /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 00000000000..c37fcc1283b --- /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 00000000000..09174fdb095 --- /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 00000000000..98868ad51d1 --- /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 c62374d3192..d76817c94fc 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 c457fa659e7..9ae06a9595d 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");