diff options
author | Martin Liska <mliska@suse.cz> | 2022-09-05 10:44:56 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-09-05 10:44:56 +0200 |
commit | d8e441f4b8698f38e4564fe1bbe9ff112814ecff (patch) | |
tree | 62aac45da0a2358e1ea29a07ab734f607a201e5b /gcc/c-family | |
parent | 4483fe115cef3eea1d64e913816e2d117b38ac73 (diff) | |
parent | ca60bd93e216ae0425f790e1d4f4dc4a48763c0e (diff) | |
download | gcc-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/ChangeLog | 72 | ||||
-rw-r--r-- | gcc/c-family/c-attribs.cc | 7 | ||||
-rw-r--r-- | gcc/c-family/c-common.cc | 33 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 46 | ||||
-rw-r--r-- | gcc/c-family/c-cppbuiltin.cc | 1 | ||||
-rw-r--r-- | gcc/c-family/c-lex.cc | 14 | ||||
-rw-r--r-- | gcc/c-family/c-omp.cc | 22 | ||||
-rw-r--r-- | gcc/c-family/c-opts.cc | 12 | ||||
-rw-r--r-- | gcc/c-family/c-pragma.h | 1 | ||||
-rw-r--r-- | gcc/c-family/c-pretty-print.cc | 7 | ||||
-rw-r--r-- | gcc/c-family/c-warn.cc | 94 | ||||
-rw-r--r-- | gcc/c-family/c.opt | 12 |
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 (¬e_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. |