aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-09-22 06:29:20 -0700
committerIan Lance Taylor <iant@golang.org>2022-09-22 06:29:20 -0700
commit795cffe109e28b248a54b8ee583cbae48368c2a7 (patch)
tree0c12b075c51c0d5097f26953835ae540d9f2f501 /gcc/c-family
parent9f62ed218fa656607740b386c0caa03e65dcd283 (diff)
parentf35be1268c996d993ab0b4ff329734d467474445 (diff)
downloadgcc-795cffe109e28b248a54b8ee583cbae48368c2a7.zip
gcc-795cffe109e28b248a54b8ee583cbae48368c2a7.tar.gz
gcc-795cffe109e28b248a54b8ee583cbae48368c2a7.tar.bz2
Merge from trunk revision f35be1268c996d993ab0b4ff329734d467474445.
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog140
-rw-r--r--gcc/c-family/c-attribs.cc7
-rw-r--r--gcc/c-family/c-common.cc59
-rw-r--r--gcc/c-family/c-common.h55
-rw-r--r--gcc/c-family/c-cppbuiltin.cc1
-rw-r--r--gcc/c-family/c-format.cc3
-rw-r--r--gcc/c-family/c-gimplify.cc12
-rw-r--r--gcc/c-family/c-lex.cc27
-rw-r--r--gcc/c-family/c-omp.cc28
-rw-r--r--gcc/c-family/c-opts.cc30
-rw-r--r--gcc/c-family/c-ppoutput.cc4
-rw-r--r--gcc/c-family/c-pragma.h1
-rw-r--r--gcc/c-family/c-pretty-print.cc7
-rw-r--r--gcc/c-family/c-warn.cc91
-rw-r--r--gcc/c-family/c.opt18
15 files changed, 409 insertions, 74 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 9e5f83c..ba3d76d 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,143 @@
+2022-09-15 Richard Biener <rguenther@suse.de>
+
+ * c-common.h (build_void_list_node): Remove.
+ * c-common.cc (c_common_nodes_and_builtins): Do not initialize
+ void_list_node.
+
+2022-09-09 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * c-format.cc (convert_format_name_to_system_name): Fix warning.
+
+2022-09-07 Joseph Myers <joseph@codesourcery.com>
+
+ * c-common.cc (c_common_reswords): Use D_C2X instead of D_CXXONLY
+ for alignas, alignof, bool, false, static_assert, thread_local and
+ true.
+
+2022-09-07 Jakub Jelinek <jakub@redhat.com>
+
+ * c.opt (Winvalid-utf8): Use ObjC instead of objC. Remove
+ " in comments" from description.
+ (Wunicode): New option.
+
+2022-09-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/106836
+ * c-omp.cc (c_omp_split_clauses): Handle OMP_CLAUSE_DOACROSS.
+
+2022-09-03 Jakub Jelinek <jakub@redhat.com>
+
+ * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_DOACROSS.
+ * c-omp.cc (c_finish_omp_depobj): Check also for OMP_CLAUSE_DOACROSS
+ clause and diagnose it. Don't handle OMP_CLAUSE_DEPEND_SOURCE and
+ OMP_CLAUSE_DEPEND_SINK. Assert kind is not OMP_CLAUSE_DEPEND_INVALID.
+
+2022-09-02 David Malcolm <dmalcolm@redhat.com>
+
+ PR c/90885
+ * c-common.h (check_for_xor_used_as_pow): New decl.
+ * c-lex.cc (c_lex_with_flags): Add DECIMAL_INT to flags as appropriate.
+ * c-warn.cc (check_for_xor_used_as_pow): New.
+ * c.opt (Wxor-used-as-pow): New.
+
+2022-09-01 Jason Merrill <jason@redhat.com>
+
+ * c-common.cc (c_common_nodes_and_builtins): Set TREE_STRING_FLAG on
+ char8_t.
+ (braced_list_to_string): Check for char-sized elements.
+
+2022-09-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/106655
+ * c.opt (-Winvalid-utf8): New warning.
+ * c-opts.cc (c_common_handle_option) <case OPT_finput_charset_>:
+ Set cpp_opts->cpp_input_charset_explicit.
+ (c_common_post_options): If -finput-charset=UTF-8 is explicit
+ in C++23, enable -Winvalid-utf8 by default and if -pedantic
+ or -pedantic-errors, make it a pedwarn.
+
+2022-08-31 Joseph Myers <joseph@codesourcery.com>
+
+ * c-attribs.cc (handle_deprecated_attribute): Check and pedwarn
+ for LABEL_DECL.
+ * c-common.cc (c_add_case_label): Add argument ATTRS. Call
+ decl_attributes.
+ * c-common.h (do_case, c_add_case_label): Update declarations.
+ * c-lex.cc (c_common_has_attribute): For C, produce a result of
+ 201910 for fallthrough and 202106 for maybe_unused.
+
+2022-08-26 Marek Polacek <polacek@redhat.com>
+
+ PR c++/81159
+ * c.opt (Wself-move): New option.
+
+2022-08-26 Jakub Jelinek <jakub@redhat.com>
+
+ * c-common.cc (check_builtin_function_arguments): Handle
+ BUILT_IN_ISSIGNALING.
+
+2022-08-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/106648
+ * c-cppbuiltin.cc (c_cpp_builtins): Predefine
+ __cpp_named_character_escapes to 202207L.
+
+2022-08-25 Marek Polacek <polacek@redhat.com>
+
+ * c-common.cc (c_common_reswords): Enable nullptr in C2X.
+ (c_common_nodes_and_builtins): Create the built-in node for nullptr.
+ * c-common.h (enum c_tree_index): Add CTI_NULLPTR, CTI_NULLPTR_TYPE.
+ (struct c_common_resword): Resize the disable member.
+ (D_C2X): Add.
+ (nullptr_node): Define.
+ (nullptr_type_node): Define.
+ (NULLPTR_TYPE_P): Define.
+ * c-pretty-print.cc (c_pretty_printer::simple_type_specifier): Handle
+ NULLPTR_TYPE.
+ (c_pretty_printer::direct_abstract_declarator): Likewise.
+ (c_pretty_printer::constant): Likewise.
+
+2022-08-16 Tom Honermann <tom@honermann.net>
+
+ PR c++/106423
+ * c-opts.cc (c_common_post_options): Disable -Wc++20-compat
+ diagnostics in C++20 and later.
+ * c.opt (Wc++20-compat): Enable hooks for the preprocessor.
+
+2022-08-11 Marek Polacek <polacek@redhat.com>
+
+ PR middle-end/102633
+ * c-gimplify.cc (c_gimplify_expr) <case DECL_EXPR>: Don't call
+ suppress_warning here.
+
+2022-08-08 Tom Honermann <tom@honermann.net>
+
+ PR preprocessor/106426
+ * c-opts.cc (c_common_post_options): Assign cpp_opts->unsigned_utf8char
+ subject to -fchar8_t, -fsigned-char, and/or -funsigned-char.
+
+2022-08-08 Tom Honermann <tom@honermann.net>
+
+ * c-lex.cc (lex_string, lex_charconst): Use char8_t as the type
+ of CPP_UTF8CHAR and CPP_UTF8STRING when char8_t support is
+ enabled.
+ * c-opts.cc (c_common_post_options): Set flag_char8_t if
+ targeting C2x.
+
+2022-07-31 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR c++/66290
+ * c-common.h: Rename global done_lexing to
+ override_libcpp_locations.
+ * c-common.cc (c_cpp_diagnostic): Likewise.
+ * c-opts.cc (c_common_finish): Set override_libcpp_locations
+ (formerly done_lexing) immediately prior to calling cpp_finish ().
+
+2022-07-27 Lewis Hyatt <lhyatt@gmail.com>
+
+ * c-ppoutput.cc (token_streamer::stream): Update input_location
+ prior to streaming each token.
+
2022-07-23 Immad Mir <mirimmad@outlook.com>
* c-attribs.cc: (c_common_attribute_table): add three new attributes
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index e4f1d35..8bb80e2 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -4163,6 +4163,13 @@ handle_deprecated_attribute (tree *node, tree name,
|| TREE_CODE (decl) == CONST_DECL
|| objc_method_decl (TREE_CODE (decl)))
TREE_DEPRECATED (decl) = 1;
+ else if (TREE_CODE (decl) == LABEL_DECL)
+ {
+ pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
+ name);
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
else
warn = 1;
}
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 655c3ae..c0f15f4 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -284,9 +284,11 @@ int c_inhibit_evaluation_warnings;
be generated. */
bool in_late_binary_op;
-/* Whether lexing has been completed, so subsequent preprocessor
- errors should use the compiler's input_location. */
-bool done_lexing = false;
+/* Depending on which phase of processing we are in, we may need
+ to prefer input_location to libcpp's locations. (Specifically,
+ after the C++ lexer is done lexing tokens, but prior to calling
+ cpp_finish (), we need to do so. */
+bool override_libcpp_locations;
/* Information about how a function name is generated. */
struct fname_var_t
@@ -322,8 +324,10 @@ static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT);
if they match the mask.
Masks for languages:
- C --std=c89: D_C99 | D_CXXONLY | D_OBJC | D_CXX_OBJC
- C --std=c99: D_CXXONLY | D_OBJC
+ C --std=c89: D_C99 | D_C2X | D_CXXONLY | D_OBJC | D_CXX_OBJC
+ C --std=c99: D_C2X | D_CXXONLY | D_OBJC
+ C --std=c17: D_C2X | D_CXXONLY | D_OBJC
+ C --std=c2x: D_CXXONLY | D_OBJC
ObjC is like C except that D_OBJC and D_CXX_OBJC are not set
C++ --std=c++98: D_CONLY | D_CXX11 | D_CXX20 | D_OBJC
C++ --std=c++11: D_CONLY | D_CXX20 | D_OBJC
@@ -455,11 +459,11 @@ const struct c_common_resword c_common_reswords[] =
{ "__GIMPLE", RID_GIMPLE, D_CONLY },
{ "__PHI", RID_PHI, D_CONLY },
{ "__RTL", RID_RTL, D_CONLY },
- { "alignas", RID_ALIGNAS, D_CXXONLY | D_CXX11 | D_CXXWARN },
- { "alignof", RID_ALIGNOF, D_CXXONLY | D_CXX11 | D_CXXWARN },
+ { "alignas", RID_ALIGNAS, D_C2X | D_CXX11 | D_CXXWARN },
+ { "alignof", RID_ALIGNOF, D_C2X | D_CXX11 | D_CXXWARN },
{ "asm", RID_ASM, D_ASM },
{ "auto", RID_AUTO, 0 },
- { "bool", RID_BOOL, D_CXXONLY | D_CXXWARN },
+ { "bool", RID_BOOL, D_C2X | D_CXXWARN },
{ "break", RID_BREAK, 0 },
{ "case", RID_CASE, 0 },
{ "catch", RID_CATCH, D_CXX_OBJC | D_CXXWARN },
@@ -485,7 +489,7 @@ const struct c_common_resword c_common_reswords[] =
{ "explicit", RID_EXPLICIT, D_CXXONLY | D_CXXWARN },
{ "export", RID_EXPORT, D_CXXONLY | D_CXXWARN },
{ "extern", RID_EXTERN, 0 },
- { "false", RID_FALSE, D_CXXONLY | D_CXXWARN },
+ { "false", RID_FALSE, D_C2X | D_CXXWARN },
{ "float", RID_FLOAT, 0 },
{ "for", RID_FOR, 0 },
{ "friend", RID_FRIEND, D_CXXONLY | D_CXXWARN },
@@ -498,7 +502,7 @@ const struct c_common_resword c_common_reswords[] =
{ "namespace", RID_NAMESPACE, D_CXXONLY | D_CXXWARN },
{ "new", RID_NEW, D_CXXONLY | D_CXXWARN },
{ "noexcept", RID_NOEXCEPT, D_CXXONLY | D_CXX11 | D_CXXWARN },
- { "nullptr", RID_NULLPTR, D_CXXONLY | D_CXX11 | D_CXXWARN },
+ { "nullptr", RID_NULLPTR, D_C2X | D_CXX11 | D_CXXWARN },
{ "operator", RID_OPERATOR, D_CXXONLY | D_CXXWARN },
{ "private", RID_PRIVATE, D_CXX_OBJC | D_CXXWARN },
{ "protected", RID_PROTECTED, D_CXX_OBJC | D_CXXWARN },
@@ -511,15 +515,15 @@ const struct c_common_resword c_common_reswords[] =
{ "signed", RID_SIGNED, 0 },
{ "sizeof", RID_SIZEOF, 0 },
{ "static", RID_STATIC, 0 },
- { "static_assert", RID_STATIC_ASSERT, D_CXXONLY | D_CXX11 | D_CXXWARN },
+ { "static_assert", RID_STATIC_ASSERT, D_C2X | D_CXX11 | D_CXXWARN },
{ "static_cast", RID_STATCAST, D_CXXONLY | D_CXXWARN },
{ "struct", RID_STRUCT, 0 },
{ "switch", RID_SWITCH, 0 },
{ "template", RID_TEMPLATE, D_CXXONLY | D_CXXWARN },
{ "this", RID_THIS, D_CXXONLY | D_CXXWARN },
- { "thread_local", RID_THREAD, D_CXXONLY | D_CXX11 | D_CXXWARN },
+ { "thread_local", RID_THREAD, D_C2X | D_CXX11 | D_CXXWARN },
{ "throw", RID_THROW, D_CXX_OBJC | D_CXXWARN },
- { "true", RID_TRUE, D_CXXONLY | D_CXXWARN },
+ { "true", RID_TRUE, D_C2X | D_CXXWARN },
{ "try", RID_TRY, D_CXX_OBJC | D_CXXWARN },
{ "typedef", RID_TYPEDEF, 0 },
{ "typename", RID_TYPENAME, D_CXXONLY | D_CXXWARN },
@@ -4501,8 +4505,6 @@ c_common_nodes_and_builtins (void)
TYPE_NAME (void_type_node) = void_name;
}
- void_list_node = build_void_list_node ();
-
/* Make a type to be the domain of a few array types
whose domains don't really matter.
200 is small enough that it always fits in size_t
@@ -4546,6 +4548,7 @@ c_common_nodes_and_builtins (void)
if (c_dialect_cxx ())
{
char8_type_node = make_unsigned_type (char8_type_size);
+ TYPE_STRING_FLAG (char8_type_node) = true;
if (flag_char8_t)
record_builtin_type (RID_CHAR8, "char8_t", char8_type_node);
@@ -4721,6 +4724,18 @@ c_common_nodes_and_builtins (void)
null_node = make_int_cst (1, 1);
TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0);
+ /* Create the built-in nullptr node. This part of its initialization is
+ common to C and C++. The front ends can further adjust its definition
+ in {c,cxx}_init_decl_processing. In particular, we aren't setting the
+ alignment here for C++ backward ABI bug compatibility. */
+ nullptr_type_node = make_node (NULLPTR_TYPE);
+ TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
+ TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
+ TYPE_UNSIGNED (nullptr_type_node) = 1;
+ TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode);
+ SET_TYPE_MODE (nullptr_type_node, ptr_mode);
+ nullptr_node = build_int_cst (nullptr_type_node, 0);
+
/* Since builtin_types isn't gc'ed, don't export these nodes. */
memset (builtin_types, 0, sizeof (builtin_types));
}
@@ -5052,11 +5067,12 @@ case_compare (splay_tree_key k1, splay_tree_key k2)
CASES is a tree containing all the case ranges processed so far;
COND is the condition for the switch-statement itself.
Returns the CASE_LABEL_EXPR created, or ERROR_MARK_NODE if no
- CASE_LABEL_EXPR is created. */
+ CASE_LABEL_EXPR is created. ATTRS are the attributes to be applied
+ to the label. */
tree
c_add_case_label (location_t loc, splay_tree cases, tree cond,
- tree low_value, tree high_value)
+ tree low_value, tree high_value, tree attrs)
{
tree type;
tree label;
@@ -5065,6 +5081,7 @@ c_add_case_label (location_t loc, splay_tree cases, tree cond,
/* Create the LABEL_DECL itself. */
label = create_artificial_label (loc);
+ decl_attributes (&label, attrs, 0);
/* If there was an error processing the switch condition, bail now
before we get more confused. */
@@ -6292,6 +6309,7 @@ check_builtin_function_arguments (location_t loc, vec<location_t> arg_loc,
case BUILT_IN_ISINF_SIGN:
case BUILT_IN_ISNAN:
case BUILT_IN_ISNORMAL:
+ case BUILT_IN_ISSIGNALING:
case BUILT_IN_SIGNBIT:
if (builtin_function_validate_nargs (loc, fndecl, nargs, 1))
{
@@ -6681,7 +6699,7 @@ c_cpp_diagnostic (cpp_reader *pfile ATTRIBUTE_UNUSED,
default:
gcc_unreachable ();
}
- if (done_lexing)
+ if (override_libcpp_locations)
richloc->set_range (0, input_location, SHOW_RANGE_WITH_CARET);
diagnostic_set_info_translated (&diagnostic, msg, ap,
richloc, dlevel);
@@ -9326,12 +9344,15 @@ braced_list_to_string (tree type, tree ctor, bool member)
if (!member && !tree_fits_uhwi_p (typesize))
return ctor;
- /* If the target char size differes from the host char size, we'd risk
+ /* If the target char size differs from the host char size, we'd risk
loosing data and getting object sizes wrong by converting to
host chars. */
if (TYPE_PRECISION (char_type_node) != CHAR_BIT)
return ctor;
+ /* STRING_CST doesn't support wide characters. */
+ gcc_checking_assert (TYPE_PRECISION (TREE_TYPE (type)) == CHAR_BIT);
+
/* If the array has an explicit bound, use it to constrain the size
of the string. If it doesn't, be sure to create a string that's
as long as implied by the index of the last zero specified via
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index f906439..2f592f5 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -375,6 +375,8 @@ enum c_tree_index
CTI_DEFAULT_FUNCTION_TYPE,
CTI_NULL,
+ CTI_NULLPTR,
+ CTI_NULLPTR_TYPE,
/* These are not types, but we have to look them up all the time. */
CTI_FUNCTION_NAME_DECL,
@@ -409,7 +411,7 @@ struct c_common_resword
{
const char *const word;
ENUM_BITFIELD(rid) const rid : 16;
- const unsigned int disable : 16;
+ const unsigned int disable : 32;
};
/* Mode used to build pointers (VOIDmode means ptr_mode). */
@@ -447,19 +449,20 @@ extern machine_mode c_default_pointer_mode;
#define D_CONLY 0x0001 /* C only (not in C++). */
#define D_CXXONLY 0x0002 /* C++ only (not in C). */
#define D_C99 0x0004 /* In C, C99 only. */
-#define D_CXX11 0x0008 /* In C++, C++11 only. */
-#define D_EXT 0x0010 /* GCC extension. */
-#define D_EXT89 0x0020 /* GCC extension incorporated in C99. */
-#define D_ASM 0x0040 /* Disabled by -fno-asm. */
-#define D_OBJC 0x0080 /* In Objective C and neither C nor C++. */
-#define D_CXX_OBJC 0x0100 /* In Objective C, and C++, but not C. */
-#define D_CXXWARN 0x0200 /* In C warn with -Wcxx-compat. */
-#define D_CXX_CONCEPTS 0x0400 /* In C++, only with concepts. */
-#define D_TRANSMEM 0X0800 /* C++ transactional memory TS. */
-#define D_CXX_CHAR8_T 0X1000 /* In C++, only with -fchar8_t. */
-#define D_CXX20 0x2000 /* In C++, C++20 only. */
-#define D_CXX_COROUTINES 0x4000 /* In C++, only with coroutines. */
-#define D_CXX_MODULES 0x8000 /* In C++, only with modules. */
+#define D_C2X 0x0008 /* In C, C2X only. */
+#define D_CXX11 0x0010 /* In C++, C++11 only. */
+#define D_EXT 0x0020 /* GCC extension. */
+#define D_EXT89 0x0040 /* GCC extension incorporated in C99. */
+#define D_ASM 0x0080 /* Disabled by -fno-asm. */
+#define D_OBJC 0x0100 /* In Objective C and neither C nor C++. */
+#define D_CXX_OBJC 0x0200 /* In Objective C, and C++, but not C. */
+#define D_CXXWARN 0x0400 /* In C warn with -Wcxx-compat. */
+#define D_CXX_CONCEPTS 0x0800 /* In C++, only with concepts. */
+#define D_TRANSMEM 0x1000 /* C++ transactional memory TS. */
+#define D_CXX_CHAR8_T 0x2000 /* In C++, only with -fchar8_t. */
+#define D_CXX20 0x4000 /* In C++, C++20 only. */
+#define D_CXX_COROUTINES 0x8000 /* In C++, only with coroutines. */
+#define D_CXX_MODULES 0x10000 /* In C++, only with modules. */
#define D_CXX_CONCEPTS_FLAGS D_CXXONLY | D_CXX_CONCEPTS
#define D_CXX_CHAR8_T_FLAGS D_CXXONLY | D_CXX_CHAR8_T
@@ -534,6 +537,9 @@ extern const unsigned int num_c_common_reswords;
/* The node for C++ `__null'. */
#define null_node c_global_trees[CTI_NULL]
+/* The nodes for `nullptr'. */
+#define nullptr_node c_global_trees[CTI_NULLPTR]
+#define nullptr_type_node c_global_trees[CTI_NULLPTR_TYPE]
extern GTY(()) tree c_global_trees[CTI_MAX];
@@ -767,10 +773,12 @@ extern int max_tinst_depth;
extern int c_inhibit_evaluation_warnings;
-/* Whether lexing has been completed, so subsequent preprocessor
- errors should use the compiler's input_location. */
+/* Depending on which phase of processing we are in, we may need
+ to prefer input_location to libcpp's locations. (Specifically,
+ after the C++ lexer is done lexing tokens, but prior to calling
+ cpp_finish (), we need to do so. */
-extern bool done_lexing;
+extern bool override_libcpp_locations;
/* C types are partitioned into three subsets: object, function, and
incomplete types. */
@@ -845,7 +853,6 @@ extern tree identifier_global_tag (tree);
extern bool names_builtin_p (const char *);
extern tree c_linkage_bindings (tree);
extern void record_builtin_type (enum rid, const char *, tree);
-extern tree build_void_list_node (void);
extern void start_fname_decls (void);
extern void finish_fname_decls (void);
extern const char *fname_as_string (int);
@@ -1007,7 +1014,10 @@ extern void c_parse_final_cleanups (void);
#define DECL_UNNAMED_BIT_FIELD(NODE) \
(DECL_C_BIT_FIELD (NODE) && !DECL_NAME (NODE))
-extern tree do_case (location_t, tree, tree);
+/* True iff TYPE is cv decltype(nullptr). */
+#define NULLPTR_TYPE_P(TYPE) (TREE_CODE (TYPE) == NULLPTR_TYPE)
+
+extern tree do_case (location_t, tree, tree, tree);
extern tree build_stmt (location_t, enum tree_code, ...);
extern tree build_real_imag_expr (location_t, enum tree_code, tree);
@@ -1035,7 +1045,8 @@ extern tree boolean_increment (enum tree_code, tree);
extern int case_compare (splay_tree_key, splay_tree_key);
-extern tree c_add_case_label (location_t, splay_tree, tree, tree, tree);
+extern tree c_add_case_label (location_t, splay_tree, tree, tree, tree,
+ tree = NULL_TREE);
extern bool c_switch_covers_all_cases_p (splay_tree, tree);
extern bool c_block_may_fallthru (const_tree);
@@ -1473,6 +1484,10 @@ extern tree do_warn_duplicated_branches_r (tree *, int *, void *);
extern void warn_for_multistatement_macros (location_t, location_t,
location_t, enum rid);
+extern void check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val,
+ location_t operator_loc,
+ tree rhs_val);
+
/* In c-attribs.cc. */
extern bool attribute_takes_identifier_p (const_tree);
extern tree handle_deprecated_attribute (tree *, tree, tree, int, bool *);
diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index 4672ae8..a1557eb 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1080,6 +1080,7 @@ c_cpp_builtins (cpp_reader *pfile)
cpp_define (pfile, "__cpp_if_consteval=202106L");
cpp_define (pfile, "__cpp_constexpr=202110L");
cpp_define (pfile, "__cpp_multidimensional_subscript=202110L");
+ cpp_define (pfile, "__cpp_named_character_escapes=202207L");
}
if (flag_concepts)
{
diff --git a/gcc/c-family/c-format.cc b/gcc/c-family/c-format.cc
index 68b94da..a6c380b 100644
--- a/gcc/c-family/c-format.cc
+++ b/gcc/c-family/c-format.cc
@@ -5111,8 +5111,7 @@ convert_format_name_to_system_name (const char *attr_name)
#ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
/* Check if format attribute is overridden by target. */
- if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES != NULL
- && TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0)
+ if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0)
{
for (i = 0; i < TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT; ++i)
{
diff --git a/gcc/c-family/c-gimplify.cc b/gcc/c-family/c-gimplify.cc
index a6f26c9..039a4b9 100644
--- a/gcc/c-family/c-gimplify.cc
+++ b/gcc/c-family/c-gimplify.cc
@@ -708,18 +708,6 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
break;
}
- case DECL_EXPR:
- /* This is handled mostly by gimplify.cc, but we have to deal with
- not warning about int x = x; as it is a GCC extension to turn off
- this warning but only if warn_init_self is zero. */
- if (VAR_P (DECL_EXPR_DECL (*expr_p))
- && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
- && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
- && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
- && !warn_init_self)
- suppress_warning (DECL_EXPR_DECL (*expr_p), OPT_Winit_self);
- break;
-
case PREINCREMENT_EXPR:
case PREDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc
index 8bfa4f4..110d029 100644
--- a/gcc/c-family/c-lex.cc
+++ b/gcc/c-family/c-lex.cc
@@ -381,12 +381,14 @@ c_common_has_attribute (cpp_reader *pfile, bool std_syntax)
}
else
{
- if (is_attribute_p ("deprecated", attr_name)
- || is_attribute_p ("maybe_unused", attr_name)
- || is_attribute_p ("fallthrough", attr_name))
+ if (is_attribute_p ("deprecated", attr_name))
result = 201904;
+ else if (is_attribute_p ("fallthrough", attr_name))
+ result = 201910;
else if (is_attribute_p ("nodiscard", attr_name))
result = 202003;
+ else if (is_attribute_p ("maybe_unused", attr_name))
+ result = 202106;
}
if (result)
attr_name = NULL_TREE;
@@ -509,7 +511,11 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
/* C++ uses '0' to mark virtual functions as pure.
Set PURE_ZERO to pass this information to the C++ parser. */
if (tok->val.str.len == 1 && *tok->val.str.text == '0')
- add_flags = PURE_ZERO;
+ add_flags = PURE_ZERO | DECIMAL_INT;
+ else if ((flags & CPP_N_INTEGER) && (flags & CPP_N_DECIMAL))
+ /* -Wxor-used-as-pow is only active for LHS of ^ expressed
+ as a decimal integer. */
+ add_flags = DECIMAL_INT;
*value = interpret_integer (tok, flags, &overflow);
break;
@@ -1352,7 +1358,14 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
default:
case CPP_STRING:
case CPP_UTF8STRING:
- value = build_string (1, "");
+ if (type == CPP_UTF8STRING && flag_char8_t)
+ {
+ value = build_string (TYPE_PRECISION (char8_type_node)
+ / TYPE_PRECISION (char_type_node),
+ ""); /* char8_t is 8 bits */
+ }
+ else
+ value = build_string (1, "");
break;
case CPP_STRING16:
value = build_string (TYPE_PRECISION (char16_type_node)
@@ -1425,9 +1438,7 @@ lex_charconst (const cpp_token *token)
type = char16_type_node;
else if (token->type == CPP_UTF8CHAR)
{
- if (!c_dialect_cxx ())
- type = unsigned_char_type_node;
- else if (flag_char8_t)
+ if (flag_char8_t)
type = char8_type_node;
else
type = char_type_node;
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index 66d17a2..1b086d8 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -714,8 +714,17 @@ c_finish_omp_depobj (location_t loc, tree depobj,
if (clause)
{
- gcc_assert (TREE_CODE (clause) == OMP_CLAUSE
- && OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_DEPEND);
+ gcc_assert (TREE_CODE (clause) == OMP_CLAUSE);
+ if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_DOACROSS)
+ {
+ error_at (OMP_CLAUSE_LOCATION (clause),
+ "%<depend(%s)%> is only allowed in %<omp ordered%>",
+ OMP_CLAUSE_DOACROSS_KIND (clause)
+ == OMP_CLAUSE_DOACROSS_SOURCE
+ ? "source" : "sink");
+ return;
+ }
+ gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_DEPEND);
if (OMP_CLAUSE_CHAIN (clause))
error_at (OMP_CLAUSE_LOCATION (clause),
"more than one locator in %<depend%> clause on %<depobj%> "
@@ -727,13 +736,6 @@ c_finish_omp_depobj (location_t loc, tree depobj,
"%<depobj%> dependence type specified in %<depend%> "
"clause on %<depobj%> construct");
return;
- case OMP_CLAUSE_DEPEND_SOURCE:
- case OMP_CLAUSE_DEPEND_SINK:
- error_at (OMP_CLAUSE_LOCATION (clause),
- "%<depend(%s)%> is only allowed in %<omp ordered%>",
- OMP_CLAUSE_DEPEND_KIND (clause) == OMP_CLAUSE_DEPEND_SOURCE
- ? "source" : "sink");
- return;
case OMP_CLAUSE_DEPEND_IN:
case OMP_CLAUSE_DEPEND_OUT:
case OMP_CLAUSE_DEPEND_INOUT:
@@ -765,7 +767,7 @@ c_finish_omp_depobj (location_t loc, tree depobj,
}
}
else
- gcc_assert (kind != OMP_CLAUSE_DEPEND_SOURCE);
+ gcc_assert (kind != OMP_CLAUSE_DEPEND_INVALID);
if (depobj == error_mark_node)
return;
@@ -1875,6 +1877,12 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
case OMP_CLAUSE_DEPEND:
s = C_OMP_CLAUSE_SPLIT_TARGET;
break;
+ case OMP_CLAUSE_DOACROSS:
+ /* This can happen with invalid depend(source) or
+ depend(sink:vec) on target combined with other constructs. */
+ gcc_assert (OMP_CLAUSE_DOACROSS_DEPEND (clauses));
+ s = C_OMP_CLAUSE_SPLIT_TARGET;
+ break;
case OMP_CLAUSE_NUM_TEAMS:
s = C_OMP_CLAUSE_SPLIT_TEAMS;
break;
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index b9f01a6..babaa2f 100644
--- a/gcc/c-family/c-opts.cc
+++ b/gcc/c-family/c-opts.cc
@@ -534,6 +534,7 @@ c_common_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
case OPT_finput_charset_:
cpp_opts->input_charset = arg;
+ cpp_opts->cpp_input_charset_explicit = 1;
break;
case OPT_ftemplate_depth_:
@@ -1046,6 +1047,13 @@ c_common_post_options (const char **pfilename)
else if (warn_narrowing == -1)
warn_narrowing = 0;
+ if (cxx_dialect >= cxx20)
+ {
+ /* Don't warn about C++20 compatibility changes in C++20 or later. */
+ warn_cxx20_compat = 0;
+ cpp_opts->cpp_warn_cxx20_compat = 0;
+ }
+
/* C++17 has stricter evaluation order requirements; let's use some of them
for earlier C++ as well, so chaining works as expected. */
if (c_dialect_cxx ()
@@ -1059,9 +1067,10 @@ c_common_post_options (const char **pfilename)
if (flag_sized_deallocation == -1)
flag_sized_deallocation = (cxx_dialect >= cxx14);
- /* char8_t support is new in C++20. */
+ /* char8_t support is implicitly enabled in C++20 and C2X. */
if (flag_char8_t == -1)
- flag_char8_t = (cxx_dialect >= cxx20);
+ flag_char8_t = (cxx_dialect >= cxx20) || flag_isoc2x;
+ cpp_opts->unsigned_utf8char = flag_char8_t ? 1 : cpp_opts->unsigned_char;
if (flag_extern_tls_init)
{
@@ -1144,6 +1153,17 @@ c_common_post_options (const char **pfilename)
lang_hooks.preprocess_options (parse_in);
cpp_post_options (parse_in);
init_global_opts_from_cpp (&global_options, cpp_get_options (parse_in));
+ /* For C++23 and explicit -finput-charset=UTF-8, turn on -Winvalid-utf8
+ by default and make it a pedwarn unless -Wno-invalid-utf8. */
+ if (cxx_dialect >= cxx23
+ && cpp_opts->cpp_input_charset_explicit
+ && strcmp (cpp_opts->input_charset, "UTF-8") == 0
+ && (cpp_opts->cpp_warn_invalid_utf8
+ || !global_options_set.x_warn_invalid_utf8))
+ {
+ global_options.x_warn_invalid_utf8 = 1;
+ cpp_opts->cpp_warn_invalid_utf8 = cpp_opts->cpp_pedantic ? 2 : 1;
+ }
/* Let diagnostics infrastructure know how to convert input files the same
way libcpp will do it, namely using the configured input charset and
@@ -1281,6 +1301,12 @@ c_common_finish (void)
}
}
+ /* When we call cpp_finish (), it may generate some diagnostics using
+ locations it remembered from the preprocessing phase, e.g. for
+ -Wunused-macros. So inform c_cpp_diagnostic () not to override those
+ locations with input_location, which would be incorrect now. */
+ override_libcpp_locations = false;
+
/* For performance, avoid tearing down cpplib's internal structures
with cpp_destroy (). */
cpp_finish (parse_in, deps_stream);
diff --git a/gcc/c-family/c-ppoutput.cc b/gcc/c-family/c-ppoutput.cc
index cd38c96..98081cc 100644
--- a/gcc/c-family/c-ppoutput.cc
+++ b/gcc/c-family/c-ppoutput.cc
@@ -210,6 +210,10 @@ void
token_streamer::stream (cpp_reader *pfile, const cpp_token *token,
location_t loc)
{
+ /* Keep input_location up to date, since it is needed for processing early
+ pragmas such as #pragma GCC diagnostic. */
+ input_location = loc;
+
if (token->type == CPP_PADDING)
{
avoid_paste = true;
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index de806a6..c894a25 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -108,6 +108,7 @@ enum pragma_omp_clause {
PRAGMA_OMP_CLAUSE_DEVICE,
PRAGMA_OMP_CLAUSE_DEVICE_TYPE,
PRAGMA_OMP_CLAUSE_DIST_SCHEDULE,
+ PRAGMA_OMP_CLAUSE_DOACROSS,
PRAGMA_OMP_CLAUSE_ENTER,
PRAGMA_OMP_CLAUSE_FILTER,
PRAGMA_OMP_CLAUSE_FINAL,
diff --git a/gcc/c-family/c-pretty-print.cc b/gcc/c-family/c-pretty-print.cc
index 71a0cb5..efa1768 100644
--- a/gcc/c-family/c-pretty-print.cc
+++ b/gcc/c-family/c-pretty-print.cc
@@ -321,6 +321,7 @@ pp_c_pointer (c_pretty_printer *pp, tree t)
_Bool -- C99
_Complex -- C99
_Imaginary -- C99
+ nullptr_t -- C23
struct-or-union-specifier
enum-specifier
typedef-name.
@@ -424,6 +425,9 @@ c_pretty_printer::simple_type_specifier (tree t)
else
translate_string ("<anonymous>");
break;
+ case NULLPTR_TYPE:
+ pp_c_ws_string (this, "nullptr_t");
+ break;
default:
pp_unsupported_tree (this, t);
@@ -678,6 +682,7 @@ c_pretty_printer::direct_abstract_declarator (tree t)
case COMPLEX_TYPE:
case TYPE_DECL:
case ERROR_MARK:
+ case NULLPTR_TYPE:
break;
default:
@@ -1219,6 +1224,8 @@ c_pretty_printer::constant (tree e)
pp_c_character_constant (this, e);
else if (TREE_CODE (type) == ENUMERAL_TYPE)
pp_c_enumeration_constant (this, e);
+ else if (NULLPTR_TYPE_P (type))
+ pp_string (this, "nullptr");
else
pp_c_integer_constant (this, e);
}
diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index ea7335f..6742f44 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -3799,3 +3799,94 @@ do_warn_array_compare (location_t location, tree_code code, tree op0, tree op1)
op0, op_symbol_code (code), op1);
}
}
+
+/* Given LHS_VAL ^ RHS_VAL, where LHS_LOC is the location of the LHS and
+ OPERATOR_LOC is the location of the ^, complain with -Wxor-used-as-pow
+ if it looks like the user meant exponentiation rather than xor. */
+
+void
+check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val,
+ location_t operator_loc,
+ tree rhs_val)
+{
+ /* Only complain if both args are non-negative integer constants that fit
+ in uhwi. */
+ if (!tree_fits_uhwi_p (lhs_val) || !tree_fits_uhwi_p (rhs_val))
+ return;
+
+ /* Only complain if the LHS is 2 or 10. */
+ unsigned HOST_WIDE_INT lhs_uhwi = tree_to_uhwi (lhs_val);
+ if (lhs_uhwi != 2 && lhs_uhwi != 10)
+ return;
+
+ unsigned HOST_WIDE_INT rhs_uhwi = tree_to_uhwi (rhs_val);
+ unsigned HOST_WIDE_INT xor_result = lhs_uhwi ^ rhs_uhwi;
+ binary_op_rich_location loc (operator_loc,
+ lhs_val, rhs_val, false);
+
+ /* If we issue fix-it hints with the warning then we will also issue a
+ note suggesting how to suppress the warning with a different change.
+ These proposed changes are incompatible. */
+ loc.fixits_cannot_be_auto_applied ();
+
+ auto_diagnostic_group d;
+ bool warned = false;
+ if (lhs_uhwi == 2)
+ {
+ /* Would exponentiation fit in int, in long long, or not at all? */
+ if (rhs_uhwi < (INT_TYPE_SIZE - 1))
+ {
+ unsigned HOST_WIDE_INT suggested_result = 1 << rhs_uhwi;
+ loc.add_fixit_replace (lhs_loc, "1");
+ loc.add_fixit_replace (operator_loc, "<<");
+ warned = warning_at (&loc, OPT_Wxor_used_as_pow,
+ "result of %<%wu^%wu%> is %wu;"
+ " did you mean %<1 << %wu%> (%wu)?",
+ lhs_uhwi, rhs_uhwi, xor_result,
+ rhs_uhwi, suggested_result);
+ }
+ else if (rhs_uhwi < (LONG_LONG_TYPE_SIZE - 1))
+ {
+ loc.add_fixit_replace (lhs_loc, "1LL");
+ loc.add_fixit_replace (operator_loc, "<<");
+ warned = warning_at (&loc, OPT_Wxor_used_as_pow,
+ "result of %<%wu^%wu%> is %wu;"
+ " did you mean %<1LL << %wu%>?",
+ lhs_uhwi, rhs_uhwi, xor_result,
+ rhs_uhwi);
+ }
+ else if (rhs_uhwi <= LONG_LONG_TYPE_SIZE)
+ warned = warning_at (&loc, OPT_Wxor_used_as_pow,
+ "result of %<%wu^%wu%> is %wu;"
+ " did you mean exponentiation?",
+ lhs_uhwi, rhs_uhwi, xor_result);
+ /* Otherwise assume it's an xor. */
+ }
+ else
+ {
+ gcc_assert (lhs_uhwi == 10);
+ loc.add_fixit_replace (lhs_loc, "1");
+ loc.add_fixit_replace (operator_loc, "e");
+ warned = warning_at (&loc, OPT_Wxor_used_as_pow,
+ "result of %<%wu^%wu%> is %wu;"
+ " did you mean %<1e%wu%>?",
+ lhs_uhwi, rhs_uhwi, xor_result,
+ rhs_uhwi);
+ }
+ if (warned)
+ {
+ gcc_rich_location note_loc (lhs_loc);
+ if (lhs_uhwi == 2)
+ note_loc.add_fixit_replace (lhs_loc, "0x2");
+ else
+ {
+ gcc_assert (lhs_uhwi == 10);
+ note_loc.add_fixit_replace (lhs_loc, "0xa");
+ }
+ note_loc.fixits_cannot_be_auto_applied ();
+ inform (&note_loc,
+ "you can silence this warning by using a hexadecimal constant"
+ " (%wx rather than %wd)",
+ lhs_uhwi, lhs_uhwi);
+ }
+}
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 44e1a60..1c7f89e 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -455,7 +455,7 @@ Wc++2a-compat
C++ ObjC++ Warning Alias(Wc++20-compat) Undocumented
Wc++20-compat
-C++ ObjC++ Var(warn_cxx20_compat) Warning LangEnabledBy(C++ ObjC++,Wall)
+C++ ObjC++ Var(warn_cxx20_compat) Warning LangEnabledBy(C++ ObjC++,Wall) Init(0) CPP(cpp_warn_cxx20_compat) CppReason(CPP_W_CXX20_COMPAT)
Warn about C++ constructs whose meaning differs between ISO C++ 2017 and ISO C++ 2020.
Wc++11-extensions
@@ -821,6 +821,10 @@ Winvalid-pch
C ObjC C++ ObjC++ CPP(warn_invalid_pch) CppReason(CPP_W_INVALID_PCH) Var(cpp_warn_invalid_pch) Init(0) Warning
Warn about PCH files that are found but not used.
+Winvalid-utf8
+C ObjC C++ ObjC++ CPP(cpp_warn_invalid_utf8) CppReason(CPP_W_INVALID_UTF8) Var(warn_invalid_utf8) Init(0) Warning
+Warn about invalid UTF-8 characters.
+
Wjump-misses-init
C ObjC Var(warn_jump_misses_init) Warning LangEnabledby(C ObjC,Wc++-compat)
Warn when a jump misses a variable initialization.
@@ -1229,6 +1233,10 @@ Wselector
ObjC ObjC++ Var(warn_selector) Warning
Warn if a selector has multiple methods.
+Wself-move
+C++ ObjC++ Var(warn_self_move) Warning LangEnabledBy(C++ ObjC++, Wall)
+Warn when a value is moved to itself with std::move.
+
Wsequence-point
C ObjC C++ ObjC++ Var(warn_sequence_point) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn about possible violations of sequence point rules.
@@ -1337,6 +1345,10 @@ Wundef
C ObjC C++ ObjC++ CPP(warn_undef) CppReason(CPP_W_UNDEF) Var(cpp_warn_undef) Init(0) Warning
Warn if an undefined macro is used in an #if directive.
+Wunicode
+C ObjC C++ ObjC++ CPP(cpp_warn_unicode) CppReason(CPP_W_UNICODE) Var(warn_unicode) Init(1) Warning
+Warn about invalid forms of delimited or named escape sequences.
+
Wuninitialized
C ObjC C++ ObjC++ LTO LangEnabledBy(C ObjC C++ ObjC++ LTO,Wall)
;
@@ -1439,6 +1451,10 @@ Wwrite-strings
C ObjC C++ ObjC++ Var(warn_write_strings) Warning
In C++, nonzero means warn about deprecated conversion from string literals to 'char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard.
+Wxor-used-as-pow
+C ObjC C++ ObjC++ Var(warn_xor_used_as_pow) Warning Init(1)
+Warn about xor operators where it appears the user meant exponentiation.
+
Wzero-as-null-pointer-constant
C++ ObjC++ Var(warn_zero_as_null_pointer_constant) Warning
Warn when a literal '0' is used as null pointer.