aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorJoseph Myers <josmyers@redhat.com>2024-06-11 23:00:04 +0000
committerJoseph Myers <josmyers@redhat.com>2024-06-11 23:00:04 +0000
commit0cf68222d2df3af7fefad28a82fcd51d8b40a192 (patch)
tree701b30abd2d7acb11f081f6f9de304ef119189cf /gcc/c
parent6bc26cceb243c6f359f65a1afa5515f911f3327d (diff)
downloadgcc-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.cc39
-rw-r--r--gcc/c/c-parser.cc82
-rw-r--r--gcc/c/c-tree.h2
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,