aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-09-05 10:44:56 +0200
committerMartin Liska <mliska@suse.cz>2022-09-05 10:44:56 +0200
commitd8e441f4b8698f38e4564fe1bbe9ff112814ecff (patch)
tree62aac45da0a2358e1ea29a07ab734f607a201e5b /gcc/c-family
parent4483fe115cef3eea1d64e913816e2d117b38ac73 (diff)
parentca60bd93e216ae0425f790e1d4f4dc4a48763c0e (diff)
downloadgcc-d8e441f4b8698f38e4564fe1bbe9ff112814ecff.zip
gcc-d8e441f4b8698f38e4564fe1bbe9ff112814ecff.tar.gz
gcc-d8e441f4b8698f38e4564fe1bbe9ff112814ecff.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog72
-rw-r--r--gcc/c-family/c-attribs.cc7
-rw-r--r--gcc/c-family/c-common.cc33
-rw-r--r--gcc/c-family/c-common.h46
-rw-r--r--gcc/c-family/c-cppbuiltin.cc1
-rw-r--r--gcc/c-family/c-lex.cc14
-rw-r--r--gcc/c-family/c-omp.cc22
-rw-r--r--gcc/c-family/c-opts.cc12
-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.cc94
-rw-r--r--gcc/c-family/c.opt12
12 files changed, 285 insertions, 36 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index c738e57..3fcf73b 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,75 @@
+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
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 6e41ceb..9746504 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -324,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
@@ -500,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 },
@@ -4548,6 +4550,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);
@@ -4723,6 +4726,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));
}
@@ -5054,11 +5069,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;
@@ -5067,6 +5083,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. */
@@ -6294,6 +6311,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))
{
@@ -9328,12 +9346,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 c06769b..ce971a2 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];
@@ -1009,7 +1015,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);
@@ -1037,7 +1046,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);
@@ -1475,6 +1485,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-lex.cc b/gcc/c-family/c-lex.cc
index 0b6f94e..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;
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index 66d17a2..56bc4b1 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;
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index 337a524..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_:
@@ -1152,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
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..ed79cc3 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -3799,3 +3799,97 @@ 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. */
+ if (!(TREE_CODE (lhs_val) == INTEGER_CST
+ && tree_int_cst_sgn (lhs_val) >= 0))
+ return;
+ if (!(TREE_CODE (rhs_val) == INTEGER_CST
+ && tree_int_cst_sgn (rhs_val) >= 0))
+ 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 dfdebd5..4515664 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -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 in comments.
+
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.
@@ -1439,6 +1447,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.