diff options
author | Joseph Myers <josmyers@redhat.com> | 2024-06-11 23:00:04 +0000 |
---|---|---|
committer | Joseph Myers <josmyers@redhat.com> | 2024-06-11 23:00:04 +0000 |
commit | 0cf68222d2df3af7fefad28a82fcd51d8b40a192 (patch) | |
tree | 701b30abd2d7acb11f081f6f9de304ef119189cf /gcc/c | |
parent | 6bc26cceb243c6f359f65a1afa5515f911f3327d (diff) | |
download | gcc-0cf68222d2df3af7fefad28a82fcd51d8b40a192.zip gcc-0cf68222d2df3af7fefad28a82fcd51d8b40a192.tar.gz gcc-0cf68222d2df3af7fefad28a82fcd51d8b40a192.tar.bz2 |
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.
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/c-errors.cc | 39 | ||||
-rw-r--r-- | gcc/c/c-parser.cc | 82 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 2 |
3 files changed, 95 insertions, 28 deletions
diff --git a/gcc/c/c-errors.cc b/gcc/c/c-errors.cc index 7aa5e0d..f36e7f9 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 0c50181..e83e9c6 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 56a33b8..15da875 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, |