aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog664
-rw-r--r--gcc/c-family/c-ada-spec.cc26
-rw-r--r--gcc/c-family/c-attribs.cc389
-rw-r--r--gcc/c-family/c-common.cc249
-rw-r--r--gcc/c-family/c-common.def9
-rw-r--r--gcc/c-family/c-common.h21
-rw-r--r--gcc/c-family/c-cppbuiltin.cc81
-rw-r--r--gcc/c-family/c-format.cc27
-rw-r--r--gcc/c-family/c-format.h1
-rw-r--r--gcc/c-family/c-gimplify.cc38
-rw-r--r--gcc/c-family/c-indentation.cc21
-rw-r--r--gcc/c-family/c-lex.cc2
-rw-r--r--gcc/c-family/c-omp.cc351
-rw-r--r--gcc/c-family/c-opts.cc114
-rw-r--r--gcc/c-family/c-pch.cc12
-rw-r--r--gcc/c-family/c-pragma.cc19
-rw-r--r--gcc/c-family/c-pragma.h1
-rw-r--r--gcc/c-family/c-pretty-print.cc77
-rw-r--r--gcc/c-family/c-pretty-print.h8
-rw-r--r--gcc/c-family/c-ubsan.cc333
-rw-r--r--gcc/c-family/c-warn.cc592
-rw-r--r--gcc/c-family/c.opt138
-rw-r--r--gcc/c-family/c.opt.urls52
-rw-r--r--gcc/c-family/known-headers.cc7
-rw-r--r--gcc/c-family/known-headers.h4
25 files changed, 2650 insertions, 586 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 1572c8b..87c06f6 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,667 @@
+2025-12-05 Tobias Burnus <tburnus@baylibre.com>
+
+ * c-omp.cc (c_omp_split_clauses): Handle
+ OMP_CLAUSE_DYN_GROUPPRIVATE, sort target clauses
+ alphabetically.
+ * c-pragma.h (enum pragma_omp_clause): Add
+ PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE.
+
+2025-11-30 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ * c.opt.urls: Regenerate.
+
+2025-11-26 Alejandro Colomar <alx@kernel.org>
+
+ * c-common.cc (c_common_reswords): Add _Maxof & _Minof keywords.
+ (c_maxof_type, c_minof_type): New functions.
+ * c-common.def (MAXOF_EXPR, MINOF_EXPR): New trees.
+ * c-common.h (enum rid): Add RID_MAXOF & RID_MINOF constants.
+ (c_maxof_type, c_minof_type): New prototypes.
+
+2025-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ * c-opts.cc (c_common_init_options): Call set_std_cxx20 rather than
+ set_std_cxx17.
+ * c.opt (std=c++2a): Change description to deprecated option wording.
+ (std=c++20): Remove experimental support part.
+ (std=c++2b): Change description to deprecated option wording.
+ (std=gnu++2a): Likewise.
+ (std=gnu++20): Remove experimental support part.
+ (std=gnu++2b): Change description to deprecated option wording.
+
+2025-11-25 Jason Merrill <jason@redhat.com>
+
+ * c.opt: Add --compile-std-module.
+
+2025-11-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/120052
+ * c-ubsan.cc (ubsan_instrument_bounds): For VLAs use
+ 1 instead of 0 as first IFN_UBSAN_BOUNDS argument and only
+ use the addend without TYPE_MAX_VALUE (TYPE_DOMAIN (type))
+ in the 3rd argument.
+
+2025-11-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/122624
+ * c-common.cc (c_common_get_alias_set): Fix up handling of BITINT_TYPE
+ and non-standard INTEGER_TYPEs. For unsigned _BitInt(1) always return
+ -1. For other unsigned types set TYPE_ALIAS_SET to get_alias_set of
+ corresponding signed type and return that. For signed types check if
+ corresponding unsigned type has TYPE_ALIAS_SET_KNOWN_P and if so copy
+ its TYPE_ALIAS_SET and return that.
+
+2025-11-25 Kito Cheng <kito.cheng@sifive.com>
+
+ * c-opts.cc (c_common_post_options): Skip register_include_chains
+ when cpp_opts->preprocessed is set.
+
+2025-11-22 Sandra Loosemore <sloosemore@baylibre.com>
+ Julian Brown <julian@codesourcery.com>
+ waffl3x <waffl3x@baylibre.com>
+
+ * c-omp.cc (c_omp_directives): Uncomment "begin declare variant"
+ and "end declare variant".
+
+2025-11-11 Alejandro Colomar <alx@kernel.org>
+
+ * c-warn.cc (warn_parms_array_mismatch): Split out body of
+ per-pair in parameter lists iteration into...
+ (warn_parm_array_mismatch): ...this new function.
+
+2025-11-11 Alejandro Colomar <alx@kernel.org>
+
+ * c-warn.cc (warn_parms_array_mismatch): Reduce scope of local
+ variable.
+
+2025-11-10 Sandra Loosemore <sloosemore@baylibre.com>
+
+ PR other/122243
+ * c.opt.urls: Regenerated.
+
+2025-11-10 Alejandro Colomar <alx@kernel.org>
+
+ PR c/122591
+ * c-common.cc (c_countof_type): Convert return value to size_t.
+
+2025-11-10 Sandra Loosemore <sloosemore@baylibre.com>
+
+ PR other/122243
+ * c.opt (fmodule-version-ignore): Mark as "Undocumented".
+
+2025-11-10 Sandra Loosemore <sloosemore@baylibre.com>
+
+ PR other/122243
+ * c.opt: (fdeps-format=): Add RejectNegative.
+ (fdeps-file=): Likewise.
+ (fdeps-target=): Likewise.
+ (Walloc-size-larger-than=): Likewise.
+ (Wno-alloc-size-larger-than): Likewise.
+ (Walloca-larger-than=): Likewise.
+ (Wno-alloca-larger-than): Likewise.
+ (Woverloaded-virtual=): Likewise.
+ (Wvla-larger-than=): Likewise.
+ (Wno-vla-larger-than): Likewise.
+ (fopenacc-dim=): Likewise.
+ (femit-struct-debug-baseonly): Likewise.
+ (femit-struct-debug-reduced): Likewise.
+ (femit-struct-debug-detailed=): Likewise.
+
+2025-11-10 Sandra Loosemore <sloosemore@baylibre.com>
+
+ PR other/122243
+ * c.opt (Wsynth): Mark as "Ignore".
+
+2025-11-10 Tejas Belagod <tejas.belagod@arm.com>
+
+ * c-common.cc (c_build_vec_convert): Support vector boolean
+ types for __builtin_convertvector ().
+
+2025-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/119064
+ * c-cppbuiltin.cc (c_cpp_builtins): Revert 2025-07-11
+ changes.
+
+2025-11-10 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR preprocessor/105608
+ * c-opts.cc (c_finish_options): Set new member
+ line_table->cmdline_location.
+ * c-pch.cc (c_common_read_pch): Adapt linemap usage to changes in
+ libcpp pch.cc; it is now possible that the linemap is in a different
+ file after returning from cpp_read_state().
+
+2025-11-05 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/121574
+ * c.opt: New warning '-Wexpose-global-module-tu-local'.
+ * c.opt.urls: Regenerate.
+
+2025-11-04 Alejandro Colomar <alx@kernel.org>
+
+ * c-warn.cc (warn_parms_array_mismatch): Fix typos in comment.
+
+2025-11-04 Alejandro Colomar <alx@kernel.org>
+
+ * c-common.h (warn_parm_array_mismatch):
+ Rename warn_parm_array_mismatch => warn_parms_array_mismatch.
+ * c-warn.cc (warn_parm_array_mismatch):
+ Rename warn_parm_array_mismatch => warn_parms_array_mismatch.
+
+2025-10-30 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-attribs.cc (handle_counted_by_attribute): Allow counted_by for
+ void pointer. Issue warnings when -Wpointer-arith is present.
+
+2025-10-27 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/122325
+ * c-opts.cc (c_common_init_options_struct): Remove set of
+ flag_default_complex_method.
+
+2025-10-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/122302
+ * c-common.cc (braced_list_to_string): Call copy_node on RAW_DATA_CST
+ before changing RAW_DATA_POINTER and RAW_DATA_LENGTH on it.
+
+2025-10-21 Tobias Burnus <tburnus@baylibre.com>
+
+ * c-omp.cc (c_omp_directives): Uncomment 'declare mapper',
+ add comment to 'begin metadirective', add 6.x unimplemented
+ directives as comment-out entries.
+
+2025-10-17 Josef Melcr <jmelcr02@gmail.com>
+
+ * c-attribs.cc: Define callback attr.
+
+2025-10-14 Jakub Jelinek <jakub@redhat.com>
+
+ * c.opt (Wflex-array-member-not-at-end, Wignored-qualifiers,
+ Wopenacc-parallelism, Wstrict-flex-arrays, Wsync-nand,
+ fstrict-flex-arrays, fstrict-flex-arrays=): Enable also for ObjC and
+ ObjC++ next to C and C++.
+ (Wmisleading-indentation, Wopenmp-simd): Likewise. Also change
+ LangEnabledBy from just C C++ to C ObjC C++ ObjC++.
+ (Wplacement-new, Wplacement-new=, fcontract-assumption-mode=,
+ fcontract-build-level=, fcontract-strict-declarations=,
+ fcontract-mode=, fcontract-continuation-mode=, fcontract-role=,
+ fcontract-semantic=, fcoroutines, flang-info-include-translate,
+ flang-info-include-translate-not, flang-info-include-translate=,
+ flang-info-module-cmi, flang-info-module-cmi=): Enable also
+ for ObjC++ next to C++.
+
+2025-10-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ * c.opt: Enable Wignored-attributes for Objective-C and
+ Objective-C++.
+
+2025-10-09 David Faust <david.faust@oracle.com>
+
+ * c-attribs.cc (c_common_attribute_table): Add btf_decl_tag and
+ btf_type_tag attributes.
+ (handle_btf_decl_tag_attribute): New handler for btf_decl_tag.
+ (hanlde_btf_type_tag_attribute): New handler for btf_type_tag.
+ (btf_tag_args_ok): Helper for new attribute handlers.
+
+2025-10-09 Jakub Jelinek <jakub@redhat.com>
+
+ * c-common.h (D_CXX26): Define.
+ * c-common.cc (c_common_resword): Add D_CXX26 to
+ __builtin_c23_va_start flags, mention D_CXX26 in comment.
+
+2025-10-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/122188
+ * c-gimplify.cc (c_gimplify_expr): Also gimplify the second operand
+ before the COND_EXPR and use in COND_EXPR result of gimplification.
+
+2025-10-09 David Malcolm <dmalcolm@redhat.com>
+
+ * c-opts.cc: Define INCLUDE_VECTOR.
+
+2025-10-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/122188
+ * c-gimplify.cc (c_gimplify_expr): Gimplify CALL_EXPR_ARG (*expr_p, 0)
+ instead of calling save_expr on it.
+
+2025-10-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/114457
+ * c-opts.cc (c_common_post_options): For C++26 set
+ flag_auto_var_init to AUTO_INIT_CXX26 if not specified explicitly.
+ For C++ disable warn_trivial_auto_var_init.
+
+2025-10-04 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/117658
+ * c.opt: New flag '-Wexternal-tu-local'.
+ * c.opt.urls: Regenerate.
+
+2025-10-02 Alfie Richards <alfie.richards@arm.com>
+
+ * c-attribs.cc (attr_target_clones_exclusions): Add simd and omp
+ exclusions.
+ (attr_target_version_exclusions): New definition with simd and omp
+ exclusions.
+ (attr_omp_declare_simd_exclusions): New definition with target_version
+ and clones exclusions.
+ (attr_simd_exclusions): Ditto.
+ (c_common_gnu_attributes): Add new target_version, simd, and omp
+ declare simd variables.
+
+2025-10-01 Alejandro Colomar <alx@kernel.org>
+
+ * c.opt.urls: Regenerate
+
+2025-09-26 Alejandro Colomar <alx@kernel.org>
+
+ * c.opt: Add -Wmultiple-parameter-fwd-decl-lists
+
+2025-09-23 Alfie Richards <alfie.richards@arm.com>
+
+ * c-attribs.cc: Add support for target_version and target_clone mixing.
+
+2025-09-23 Alfie Richards <alfie.richards@arm.com>
+
+ * c-pretty-print.cc (pp_c_function_target_version): New function.
+ (pp_c_function_target_clones): New function.
+ (pp_c_maybe_whitespace): Move to c-pretty-print.h.
+ * c-pretty-print.h (pp_c_function_target_version): New function.
+ (pp_c_function_target_clones): New function.
+ (pp_c_maybe_whitespace): Moved here from c-pretty-print.cc.
+
+2025-09-23 Alfie Richards <alfie.richards@arm.com>
+
+ * c-attribs.cc (handle_target_clones_attribute): Update to use new hook.
+
+2025-09-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/121544
+ * c-ada-spec.cc (dump_ada_node) <POINTER_TYPE>: Dump the name of
+ anonymous tagged pointed-to types specially.
+ (dump_nested_type) <POINTER_TYPE>: Recurse on anonymous pointed-to
+ types declared in the same file.
+ Set TREE_VISITED on the underlying DECL of the field type, if any.
+
+2025-08-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/121520
+ * c-cppbuiltin.cc (c_cpp_builtins): Properly call cpp_warn
+ for __STDCPP_FLOAT<NN>_T__ if FLOATN_NX_TYPE_NODE (i) is NULL
+ for C++23 for non-extended types and don't call cpp_warn for
+ extended types.
+
+2025-08-18 Indu Bhagat <indu.bhagat@oracle.com>
+
+ * c-attribs.cc (add_no_sanitize_value): Use 'sanitize_code_type'
+ instead of 'unsigned int'.
+ (handle_no_sanitize_attribute): Likewise.
+ (handle_no_sanitize_address_attribute): Likewise.
+ (handle_no_sanitize_thread_attribute): Likewise.
+ (handle_no_address_safety_analysis_attribute): Likewise.
+ * c-common.h (add_no_sanitize_value): Likewise.
+
+2025-08-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/121552
+ * c.opt (Wnon-c-typedef-for-linkage): New option.
+ * c.opt.urls: Regenerate.
+
+2025-08-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ PR target/121520
+ * c-cppbuiltin.cc (c_cpp_builtins): Implement C++26 DR 2581. Add
+ cpp_define_warn lambda and use it as well as cpp_warn where needed.
+ In the if (c_dialect_cxx ()) block with __cpp_* predefinitions add
+ cpp_define lambda. Formatting fixes.
+
+2025-08-15 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-gimplify.cc (is_address_with_access_with_size): New function.
+ (ubsan_walk_array_refs_r): Instrument an INDIRECT_REF whose base
+ address is .ACCESS_WITH_SIZE or an address computation whose base
+ address is .ACCESS_WITH_SIZE.
+ * c-ubsan.cc (ubsan_instrument_bounds_pointer_address): New function.
+ (struct factor_t): New structure.
+ (get_factors_from_mul_expr): New function.
+ (get_index_from_offset): New function.
+ (get_index_from_pointer_addr_expr): New function.
+ (is_instrumentable_pointer_array_address): New function.
+ (ubsan_array_ref_instrumented_p): Change prototype.
+ Handle MEM_REF in addtional to ARRAY_REF.
+ (ubsan_maybe_instrument_array_ref): Handle MEM_REF in addtional
+ to ARRAY_REF.
+
+2025-08-15 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-attribs.cc (handle_counted_by_attribute): Accept counted_by
+ attribute for pointer fields.
+
+2025-08-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/120776
+ * c-cppbuiltin.cc (c_cpp_builtins): Predefine
+ __cpp_expansion_statements=202506L for C++26.
+
+2025-08-08 David Malcolm <dmalcolm@redhat.com>
+
+ * c-indentation.cc (should_warn_for_misleading_indentation):
+ Update for moving diagnostics::context::m_tabstop into
+ diagnostics::column_options.
+ * c-opts.cc (c_common_post_options): Likewise.
+
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/117783
+ * c-cppbuiltin.cc (c_cpp_builtins): Change __cpp_structured_bindings
+ predefined value for C++26 from 202403L to 202411L.
+
+2025-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/120778
+ * c.opt (Wkeyword-macro): New option.
+ * c.opt.urls: Regenerate.
+ * c-common.h (cxx_dialect): Comment formatting fix.
+ * c-opts.cc (c_common_post_options): Default to
+ -Wkeyword-macro for C++26 if pedantic.
+
+2025-08-06 Alexandre Oliva <oliva@adacore.com>
+
+ * c-attribs.cc (handle_hardbool_attribute): Create distinct
+ enumeration types, with structural equality. Handle
+ base type qualifiers.
+
+2025-08-02 Martin Uecker <uecker@tugraz.at>
+
+ * c-attribs.cc (handle_argspec_attribute): Update.
+ (build_arg_spec): New function.
+ (build_attr_access_from_parms): Rewrite `arg spec' handling.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-common.cc: Make diagnostics::context::m_source_printing
+ private.
+ * c-format.cc: Likewise.
+ * c-opts.cc: Likewise.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-common.cc: Update usage of "diagnostic_info" to explicitly
+ refer to "diagnostics::diagnostic_info".
+ * c-opts.cc: Likewise.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-format.cc: Update for file_cache and char_span moving from
+ input.h to diagnostics/file-cache.h and into the "diagnostics::"
+ namespace.
+ * c-indentation.cc: Likewise.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-common.cc (c_family_tests): Add include of
+ "diagnostics/diagnostics-selftests.h". Replace
+ c_diagnostic_cc_tests with
+ diagnostics::selftest::context_cc_tests.
+ * c-common.h: Drop c_diagnostic_cc_tests decl.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-common.cc: Update for diagnostic_t becoming
+ enum class diagnostics::kind.
+ * c-format.cc: Likewise.
+ * c-lex.cc: Likewise.
+ * c-opts.cc: Likewise.
+ * c-pragma.cc: Likewise.
+ * c-warn.cc: Likewise.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-common.cc: Update for renaming of diagnostic_option_id to
+ diagnostics::option_id.
+ * c-common.h: Likewise.
+ * c-cppbuiltin.cc: Likewise.
+ * known-headers.cc: Likewise.
+ * known-headers.h: Likewise.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-common.cc: Update comment for renaming of edit_context.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-format.cc (test_type_mismatch_range_labels): Update for
+ move of selftest::test_diagnostic_context to
+ diagnostics::selftest::test_context.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-format.cc: Update for move of selftest-diagnostic.h to
+ diagnostics/selftest-context.h.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-common.h: Update for diagnostic_context becoming
+ diagnostics::context.
+ * c-opts.cc: Likewise.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-opts.cc (c_diagnostic_text_finalizer): Add "m_" prefix to
+ fields of diagnostic_info.
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-opts.cc: Update for move of "diagnostic-macro-unwinding.h"
+ to "diagnostics/macro-unwinding.h".
+
+2025-07-25 David Malcolm <dmalcolm@redhat.com>
+
+ * c-opts.cc: Update for move of diagnostics output formats into
+ namespace "diagnostics" as "sinks".
+
+2025-07-16 Kwok Cheung Yeung <kcyeung@baylibre.com>
+
+ * c-omp.cc (c_finish_omp_depobj): Use OMP_ITERATOR_DECL_P.
+
+2025-07-16 Alfie Richards <alfie.richards@arm.com>
+
+ * c-attribs.cc (handle_target_clones_attribute): Change to use
+ get_clone_versions.
+
+2025-07-16 Alfie Richards <alfie.richards@arm.com>
+
+ * c-format.cc (local_string_slice_node): New node type.
+ (asm_fprintf_char_table): New entry.
+ (init_dynamic_diag_info): Add support for string_slice.
+ * c-format.h (T_STRING_SLICE): New node type.
+
+2025-07-15 Jakub Jelinek <jakub@redhat.com>
+ Jason Merrill <jason@redhat.com>
+
+ PR c/44677
+ * c-opts.cc (c_common_post_options): Change
+ warn_unused_but_set_parameter and warn_unused_but_set_variable
+ from 1 to 3 if they were set only implicitly.
+ * c-attribs.cc (build_attr_access_from_parms): Remove unused
+ but set variable nelts.
+
+2025-07-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/119064
+ * c.opt (Wc++26-compat): New option.
+ * c.opt.urls: Regenerate.
+ * c-opts.cc (c_common_post_options): Clear warn_cxx26_compat for
+ C++26 or later.
+ * c-cppbuiltin.cc (c_cpp_builtins): For C++26 predefine
+ __cpp_trivial_relocatability=202502L.
+
+2025-07-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/117785
+ * c-cppbuiltin.cc (c_cpp_builtins): Predefine
+ __cpp_constexpr_exceptions=202411L for C++26.
+
+2025-07-10 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-ubsan.cc (get_bound_from_access_with_size): Adjust the position
+ of the arguments per the new design.
+
+2025-07-07 Qing Zhao <qing.zhao@oracle.com>
+
+ Revert:
+ 2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-attribs.cc (handle_counted_by_attribute): Accept counted_by
+ attribute for pointer fields.
+
+2025-07-07 Qing Zhao <qing.zhao@oracle.com>
+
+ Revert:
+ 2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-gimplify.cc (is_address_with_access_with_size): New function.
+ (ubsan_walk_array_refs_r): Instrument an INDIRECT_REF whose base
+ address is .ACCESS_WITH_SIZE or an address computation whose base
+ address is .ACCESS_WITH_SIZE.
+ * c-ubsan.cc (ubsan_instrument_bounds_pointer_address): New function.
+ (struct factor_t): New structure.
+ (get_factors_from_mul_expr): New function.
+ (get_index_from_offset): New function.
+ (get_index_from_pointer_addr_expr): New function.
+ (is_instrumentable_pointer_array_address): New function.
+ (ubsan_array_ref_instrumented_p): Change prototype.
+ Handle MEM_REF in addtional to ARRAY_REF.
+ (ubsan_maybe_instrument_array_ref): Handle MEM_REF in addtional
+ to ARRAY_REF.
+
+2025-07-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/120917
+ * c.opt: Add -Wno-abbreviated-auto-in-template-arg.
+ * c.opt.urls: Regenerate.
+
+2025-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/120837
+ * c-common.cc (pointer_int_sum): Rewrite the intop PLUS_EXPR or
+ MINUS_EXPR optimization into extension of both intop operands,
+ their separate multiplication and then addition/subtraction followed
+ by rest of pointer_int_sum handling after the multiplication.
+
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-gimplify.cc (is_address_with_access_with_size): New function.
+ (ubsan_walk_array_refs_r): Instrument an INDIRECT_REF whose base
+ address is .ACCESS_WITH_SIZE or an address computation whose base
+ address is .ACCESS_WITH_SIZE.
+ * c-ubsan.cc (ubsan_instrument_bounds_pointer_address): New function.
+ (struct factor_t): New structure.
+ (get_factors_from_mul_expr): New function.
+ (get_index_from_offset): New function.
+ (get_index_from_pointer_addr_expr): New function.
+ (is_instrumentable_pointer_array_address): New function.
+ (ubsan_array_ref_instrumented_p): Change prototype.
+ Handle MEM_REF in addtional to ARRAY_REF.
+ (ubsan_maybe_instrument_array_ref): Handle MEM_REF in addtional
+ to ARRAY_REF.
+
+2025-07-01 Qing Zhao <qing.zhao@oracle.com>
+
+ * c-attribs.cc (handle_counted_by_attribute): Accept counted_by
+ attribute for pointer fields.
+
+2025-06-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/120520
+ PR c/117023
+ * c-attribs.cc (c_common_gnu_attributes): Allow 2 or 3 arguments for
+ nonnull_if_nonzero attribute instead of only 2.
+ (handle_nonnull_if_nonzero_attribute): Handle 3 argument
+ nonnull_if_nonzero.
+ * c-common.cc (struct nonnull_arg_ctx): Rename other member to other1,
+ add other2 member.
+ (check_function_nonnull): Clear a if nonnull attribute has an
+ argument. Adjust for nonnull_arg_ctx changes. Handle 3 argument
+ nonnull_if_nonzero attribute.
+ (check_nonnull_arg): Adjust for nonnull_arg_ctx changes, emit different
+ diagnostics for 3 argument nonnull_if_nonzero attributes.
+ (check_function_arguments): Adjust ctx var initialization.
+
+2025-06-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/120777
+ * c-cppbuiltin.cc (c_cpp_builtins): Predefine
+ __cpp_constexpr_virtual_inheritance=202506L for C++26.
+
+2025-06-26 David Malcolm <dmalcolm@redhat.com>
+
+ * c-opts.cc (c_common_diagnostics_set_defaults): Use
+ diagnostic_context::set_permissive_option.
+
+2025-06-23 Tobias Burnus <tburnus@baylibre.com>
+
+ * c-omp.cc (c_finish_oacc_wait): Handle if clause.
+
+2025-06-16 Jason Merrill <jason@redhat.com>
+
+ * c.opt: Add -Wsfinae-incomplete.
+ * c.opt.urls: Regenerate.
+
+2025-06-12 Gwenole Beauchesne <gb.devel@gmail.com>
+ Andrew Pinski <quic_apinski@quicinc.com>
+
+ PR c++/41201
+ PR c++/48026
+ * c-pragma.cc (init_pragma): Use c_register_pragma_with_early_handler
+ instead of c_register_pragma for `#pragma GCC optimize`.
+
+2025-06-03 Martin Uecker <uecker@tugraz.at>
+
+ PR c/120078
+ * c.opt (Wjump-misses-init): Fix typo.
+
+2025-05-30 Julian Brown <julian@codesourcery.com>
+ Tobias Burnus <tburnus@baylibre.com>
+
+ * c-common.h (c_omp_region_type): Add C_ORT_DECLARE_MAPPER and
+ C_ORT_OMP_DECLARE_MAPPER codes.
+ (omp_mapper_list): Add forward declaration.
+ (c_omp_find_nested_mappers, c_omp_instantiate_mappers): Add prototypes.
+ * c-omp.cc (c_omp_find_nested_mappers): New function.
+ (remap_mapper_decl_info): New struct.
+ (remap_mapper_decl_1, omp_instantiate_mapper,
+ c_omp_instantiate_mappers): New functions.
+
+2025-05-27 Alejandro Colomar <alx@kernel.org>
+ Martin Uecker <uecker@tugraz.at>
+
+ PR c/117025
+ * c-common.h (enum rid): Add RID_COUNTOF.
+ (c_countof_type): New function prototype.
+ * c-common.def (COUNTOF_EXPR): New tree.
+ * c-common.cc (c_common_reswords): Add RID_COUNTOF entry.
+ (c_countof_type): New function.
+
+2025-05-23 Jason Merrill <jason@redhat.com>
+
+ * c-format.cc (flag_chars_t::validate): Control quoting warnings
+ with -Wformat-diag.
+
+2025-05-15 Jason Merrill <jason@redhat.com>
+
+ * c-opts.cc (c_common_post_options): Set flag_coroutines.
+ (set_std_cxx20, set_std_cxx23, set_std_cxx26): Not here.
+
+2025-05-03 Jason Merrill <jason@redhat.com>
+
+ * c-opts.cc (c_common_post_options): Let plain -Wabi warn
+ about changes in a future version.
+
2025-04-28 David Malcolm <dmalcolm@redhat.com>
* c-pretty-print.cc: Drop include of "make-unique.h".
diff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc
index c7ae032..42d75b4 100644
--- a/gcc/c-family/c-ada-spec.cc
+++ b/gcc/c-family/c-ada-spec.cc
@@ -2442,8 +2442,14 @@ dump_ada_node (pretty_printer *pp, tree node, tree type, int spc,
break;
}
- dump_ada_node (pp, ref_type, ref_type, spc, is_access,
- true);
+ /* Dump anonymous tagged types specially. */
+ if (TYPE_NAME (ref_type)
+ || (!RECORD_OR_UNION_TYPE_P (ref_type)
+ && TREE_CODE (ref_type) != ENUMERAL_TYPE))
+ dump_ada_node (pp, ref_type, ref_type, spc, is_access,
+ true);
+ else
+ dump_anonymous_type_name (pp, ref_type);
}
}
}
@@ -2699,7 +2705,16 @@ dump_nested_type (pretty_printer *pp, tree field, tree t, int spc)
{
case POINTER_TYPE:
tmp = TREE_TYPE (field_type);
- dump_forward_type (pp, tmp, t, spc);
+ decl = get_underlying_decl (tmp);
+ if (TYPE_NAME (tmp) || !decl || DECL_NAME (decl))
+ dump_forward_type (pp, tmp, t, spc);
+ else if (DECL_SOURCE_FILE (decl) == DECL_SOURCE_FILE (t)
+ && !TREE_VISITED (decl))
+ {
+ /* Generate full declaration. */
+ dump_nested_type (pp, decl, t, spc);
+ TREE_VISITED (decl) = 1;
+ }
break;
case ARRAY_TYPE:
@@ -2773,6 +2788,11 @@ dump_nested_type (pretty_printer *pp, tree field, tree t, int spc)
default:
break;
}
+
+ /* Make sure not to output the nested type twice in C++. */
+ decl = get_underlying_decl (field_type);
+ if (decl)
+ TREE_VISITED (decl) = 1;
}
/* Hash table of overloaded names that we cannot support. It is needed even
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 5a0e3d3..28a034f 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pretty-print.h"
#include "gcc-rich-location.h"
#include "gcc-urlifier.h"
+#include "attr-callback.h"
static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
@@ -189,6 +190,9 @@ static tree handle_fd_arg_attribute (tree *, tree, tree, int, bool *);
static tree handle_flag_enum_attribute (tree *, tree, tree, int, bool *);
static tree handle_null_terminated_string_arg_attribute (tree *, tree, tree, int, bool *);
+static tree handle_btf_decl_tag_attribute (tree *, tree, tree, int, bool *);
+static tree handle_btf_type_tag_attribute (tree *, tree, tree, int, bool *);
+
/* Helper to define attribute exclusions. */
#define ATTR_EXCL(name, function, type, variable) \
{ name, function, type, variable }
@@ -249,12 +253,28 @@ static const struct attribute_spec::exclusions attr_target_clones_exclusions[] =
ATTR_EXCL ("always_inline", true, true, true),
ATTR_EXCL ("target", TARGET_HAS_FMV_TARGET_ATTRIBUTE,
TARGET_HAS_FMV_TARGET_ATTRIBUTE, TARGET_HAS_FMV_TARGET_ATTRIBUTE),
- ATTR_EXCL ("target_version", true, true, true),
+ ATTR_EXCL ("omp declare simd", true, true, true),
+ ATTR_EXCL ("simd", true, true, true),
ATTR_EXCL (NULL, false, false, false),
};
static const struct attribute_spec::exclusions attr_target_version_exclusions[] =
{
+ ATTR_EXCL ("omp declare simd", true, true, true),
+ ATTR_EXCL ("simd", true, true, true),
+ ATTR_EXCL (NULL, false, false, false),
+};
+
+static const struct attribute_spec::exclusions attr_omp_declare_simd_exclusions[] =
+{
+ ATTR_EXCL ("target_version", true, true, true),
+ ATTR_EXCL ("target_clones", true, true, true),
+ ATTR_EXCL (NULL, false, false, false),
+};
+
+static const struct attribute_spec::exclusions attr_simd_exclusions[] =
+{
+ ATTR_EXCL ("target_version", true, true, true),
ATTR_EXCL ("target_clones", true, true, true),
ATTR_EXCL (NULL, false, false, false),
};
@@ -465,6 +485,8 @@ const struct attribute_spec c_common_gnu_attributes[] =
handle_tm_attribute, NULL },
{ "transaction_may_cancel_outer", 0, 0, false, true, false, false,
handle_tm_attribute, NULL },
+ { CALLBACK_ATTR_IDENT, 1, -1, true, false, false, false,
+ handle_callback_attribute, NULL },
/* ??? These two attributes didn't make the transition from the
Intel language document to the multi-vendor language document. */
{ "transaction_pure", 0, 0, false, true, false, false,
@@ -489,7 +511,7 @@ const struct attribute_spec c_common_gnu_attributes[] =
handle_tls_model_attribute, NULL },
{ "nonnull", 0, -1, false, true, true, false,
handle_nonnull_attribute, NULL },
- { "nonnull_if_nonzero", 2, 2, false, true, true, false,
+ { "nonnull_if_nonzero", 2, 3, false, true, true, false,
handle_nonnull_if_nonzero_attribute, NULL },
{ "nonstring", 0, 0, true, false, false, false,
handle_nonstring_attribute, NULL },
@@ -543,7 +565,7 @@ const struct attribute_spec c_common_gnu_attributes[] =
attr_target_exclusions },
{ "target_version", 1, 1, true, false, false, false,
handle_target_version_attribute,
- attr_target_version_exclusions },
+ attr_target_version_exclusions},
{ "target_clones", 1, -1, true, false, false, false,
handle_target_clones_attribute,
attr_target_clones_exclusions },
@@ -570,7 +592,8 @@ const struct attribute_spec c_common_gnu_attributes[] =
{ "returns_nonnull", 0, 0, false, true, true, false,
handle_returns_nonnull_attribute, NULL },
{ "omp declare simd", 0, -1, true, false, false, false,
- handle_omp_declare_simd_attribute, NULL },
+ handle_omp_declare_simd_attribute,
+ attr_omp_declare_simd_exclusions },
{ "omp declare variant base", 0, -1, true, false, false, false,
handle_omp_declare_variant_attribute, NULL },
{ "omp declare variant variant", 0, -1, true, false, false, false,
@@ -579,7 +602,7 @@ const struct attribute_spec c_common_gnu_attributes[] =
false, false,
handle_omp_declare_variant_attribute, NULL },
{ "simd", 0, 1, true, false, false, false,
- handle_simd_attribute, NULL },
+ handle_simd_attribute, attr_simd_exclusions },
{ "omp declare target", 0, -1, true, false, false, false,
handle_omp_declare_target_attribute, NULL },
{ "omp declare target link", 0, 0, true, false, false, false,
@@ -640,7 +663,11 @@ const struct attribute_spec c_common_gnu_attributes[] =
{ "flag_enum", 0, 0, false, true, false, false,
handle_flag_enum_attribute, NULL },
{ "null_terminated_string_arg", 1, 1, false, true, true, false,
- handle_null_terminated_string_arg_attribute, NULL}
+ handle_null_terminated_string_arg_attribute, NULL},
+ { "btf_type_tag", 1, 1, false, true, false, false,
+ handle_btf_type_tag_attribute, NULL},
+ { "btf_decl_tag", 1, 1, true, false, false, false,
+ handle_btf_decl_tag_attribute, NULL}
};
const struct scoped_attribute_specs c_common_gnu_attribute_table =
@@ -1128,11 +1155,16 @@ handle_hardbool_attribute (tree *node, tree name, tree args,
}
tree orig = *node;
- *node = build_duplicate_type (orig);
+ /* Drop qualifiers from the base type. Keep attributes, so that, in the odd
+ chance attributes are applicable and relevant to the base type, if they
+ are specified first, or through a typedef, they wouldn't be dropped on the
+ floor here. */
+ tree unqual = build_qualified_type (orig, TYPE_UNQUALIFIED);
+ *node = build_distinct_type_copy (unqual);
TREE_SET_CODE (*node, ENUMERAL_TYPE);
- ENUM_UNDERLYING_TYPE (*node) = orig;
- TYPE_CANONICAL (*node) = TYPE_CANONICAL (orig);
+ ENUM_UNDERLYING_TYPE (*node) = unqual;
+ SET_TYPE_STRUCTURAL_EQUALITY (*node);
tree false_value;
if (args)
@@ -1191,7 +1223,13 @@ handle_hardbool_attribute (tree *node, tree name, tree args,
gcc_checking_assert (!TYPE_CACHED_VALUES_P (*node));
TYPE_VALUES (*node) = values;
- TYPE_NAME (*node) = orig;
+ TYPE_NAME (*node) = unqual;
+
+ if (TYPE_QUALS (orig) != TYPE_QUALS (*node))
+ {
+ *node = build_qualified_type (*node, TYPE_QUALS (orig));
+ TYPE_NAME (*node) = orig;
+ }
return NULL_TREE;
}
@@ -1409,23 +1447,24 @@ handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
/* Add FLAGS for a function NODE to no_sanitize_flags in DECL_ATTRIBUTES. */
void
-add_no_sanitize_value (tree node, unsigned int flags)
+add_no_sanitize_value (tree node, sanitize_code_type flags)
{
tree attr = lookup_attribute ("no_sanitize", DECL_ATTRIBUTES (node));
if (attr)
{
- unsigned int old_value = tree_to_uhwi (TREE_VALUE (attr));
+ sanitize_code_type old_value =
+ tree_to_sanitize_code_type (TREE_VALUE (attr));
flags |= old_value;
if (flags == old_value)
return;
- TREE_VALUE (attr) = build_int_cst (unsigned_type_node, flags);
+ TREE_VALUE (attr) = build_int_cst (uint64_type_node, flags);
}
else
DECL_ATTRIBUTES (node)
= tree_cons (get_identifier ("no_sanitize"),
- build_int_cst (unsigned_type_node, flags),
+ build_int_cst (uint64_type_node, flags),
DECL_ATTRIBUTES (node));
}
@@ -1436,7 +1475,7 @@ static tree
handle_no_sanitize_attribute (tree *node, tree name, tree args, int,
bool *no_add_attrs)
{
- unsigned int flags = 0;
+ sanitize_code_type flags = 0;
*no_add_attrs = true;
if (TREE_CODE (*node) != FUNCTION_DECL)
{
@@ -1473,7 +1512,7 @@ handle_no_sanitize_address_attribute (tree *node, tree name, tree, int,
if (TREE_CODE (*node) != FUNCTION_DECL)
warning (OPT_Wattributes, "%qE attribute ignored", name);
else
- add_no_sanitize_value (*node, SANITIZE_ADDRESS);
+ add_no_sanitize_value (*node, (sanitize_code_type) SANITIZE_ADDRESS);
return NULL_TREE;
}
@@ -1489,7 +1528,7 @@ handle_no_sanitize_thread_attribute (tree *node, tree name, tree, int,
if (TREE_CODE (*node) != FUNCTION_DECL)
warning (OPT_Wattributes, "%qE attribute ignored", name);
else
- add_no_sanitize_value (*node, SANITIZE_THREAD);
+ add_no_sanitize_value (*node, (sanitize_code_type) SANITIZE_THREAD);
return NULL_TREE;
}
@@ -1506,7 +1545,7 @@ handle_no_address_safety_analysis_attribute (tree *node, tree name, tree, int,
if (TREE_CODE (*node) != FUNCTION_DECL)
warning (OPT_Wattributes, "%qE attribute ignored", name);
else
- add_no_sanitize_value (*node, SANITIZE_ADDRESS);
+ add_no_sanitize_value (*node, (sanitize_code_type) SANITIZE_ADDRESS);
return NULL_TREE;
}
@@ -2906,22 +2945,55 @@ handle_counted_by_attribute (tree *node, tree name,
" declaration %q+D", name, decl);
*no_add_attrs = true;
}
- /* This attribute only applies to field with array type. */
- else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
+ /* This attribute only applies to a field with array type or pointer type. */
+ else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
+ && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
{
error_at (DECL_SOURCE_LOCATION (decl),
- "%qE attribute is not allowed for a non-array field",
- name);
+ "%qE attribute is not allowed for a non-array"
+ " or non-pointer field", name);
*no_add_attrs = true;
}
/* This attribute only applies to a C99 flexible array member type. */
- else if (! c_flexible_array_member_type_p (TREE_TYPE (decl)))
+ else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
+ && !c_flexible_array_member_type_p (TREE_TYPE (decl)))
{
error_at (DECL_SOURCE_LOCATION (decl),
"%qE attribute is not allowed for a non-flexible"
" array member field", name);
*no_add_attrs = true;
}
+ /* This attribute can be applied to a pointer to void type, but issue
+ warning when -Wpointer-arith is presenting. */
+ else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == VOID_TYPE)
+ {
+ if (warn_pointer_arith)
+ warning_at (DECL_SOURCE_LOCATION (decl),
+ OPT_Wpointer_arith,
+ "%qE attribute is used for a pointer to void",
+ name);
+ }
+ /* This attribute cannot be applied to a pointer to function type. */
+ else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "%qE attribute is not allowed for a pointer to"
+ " function", name);
+ *no_add_attrs = true;
+ }
+ /* This attribute cannot be applied to a pointer to structure or union
+ with flexible array member. */
+ else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
+ && RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
+ && TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (TREE_TYPE (decl))))
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "%qE attribute is not allowed for a pointer to"
+ " structure or union with flexible array member", name);
+ *no_add_attrs = true;
+ }
/* The argument should be an identifier. */
else if (TREE_CODE (argval) != IDENTIFIER_NODE)
{
@@ -2930,7 +3002,8 @@ handle_counted_by_attribute (tree *node, tree name,
*no_add_attrs = true;
}
/* Issue error when there is a counted_by attribute with a different
- field as the argument for the same flexible array member field. */
+ field as the argument for the same flexible array member or
+ pointer field. */
else if (old_counted_by != NULL_TREE)
{
tree old_fieldname = TREE_VALUE (TREE_VALUE (old_counted_by));
@@ -4120,10 +4193,11 @@ handle_argspec_attribute (tree *, tree, tree args, int, bool *)
{
/* Verify the attribute has one or two arguments and their kind. */
gcc_assert (args && TREE_CODE (TREE_VALUE (args)) == STRING_CST);
- for (tree next = TREE_CHAIN (args); next; next = TREE_CHAIN (next))
+ if (TREE_CHAIN (args))
{
- tree val = TREE_VALUE (next);
- gcc_assert (DECL_P (val) || EXPR_P (val));
+ tree val = TREE_VALUE (TREE_CHAIN (args));
+ gcc_assert (!TREE_CHAIN (TREE_CHAIN (args)));
+ gcc_assert (TYPE_P (val));
}
return NULL_TREE;
}
@@ -5034,12 +5108,21 @@ handle_nonnull_if_nonzero_attribute (tree *node, tree name,
tree type = *node;
tree pos = TREE_VALUE (args);
tree pos2 = TREE_VALUE (TREE_CHAIN (args));
+ tree chain2 = TREE_CHAIN (TREE_CHAIN (args));
+ tree pos3 = NULL_TREE;
+ if (chain2)
+ pos3 = TREE_VALUE (chain2);
tree val = positional_argument (type, name, pos, POINTER_TYPE, 1);
tree val2 = positional_argument (type, name, pos2, INTEGER_TYPE, 2);
- if (val && val2)
+ tree val3 = NULL_TREE;
+ if (chain2)
+ val3 = positional_argument (type, name, pos3, INTEGER_TYPE, 3);
+ if (val && val2 && (!chain2 || val3))
{
TREE_VALUE (args) = val;
TREE_VALUE (TREE_CHAIN (args)) = val2;
+ if (chain2)
+ TREE_VALUE (chain2) = val3;
}
else
*no_add_attrs = true;
@@ -5101,6 +5184,107 @@ handle_null_terminated_string_arg_attribute (tree *node, tree name, tree args,
return NULL_TREE;
}
+/* Common argument checking for btf_type_tag and btf_decl_tag.
+ Return true if the ARGS are valid, otherwise emit an error and
+ return false. */
+
+static bool
+btf_tag_args_ok (tree name, tree args)
+{
+ if (!args) /* Correct number of args (1) is checked for us. */
+ return false;
+ else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
+ {
+ error ("%qE attribute requires a string argument", name);
+ return false;
+ }
+
+ /* Only narrow character strings are accepted. */
+ tree argtype = TREE_TYPE (TREE_TYPE (TREE_VALUE (args)));
+ if (!(argtype == char_type_node
+ || argtype == char8_type_node
+ || argtype == signed_char_type_node
+ || argtype == unsigned_char_type_node))
+ {
+ error ("unsupported wide string type argument in %qE attribute", name);
+ return false;
+ }
+
+ return true;
+}
+
+/* Handle the "btf_decl_tag" attribute. */
+
+static tree
+handle_btf_decl_tag_attribute (tree * ARG_UNUSED (node), tree name, tree args,
+ int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+ if (!btf_tag_args_ok (name, args))
+ *no_add_attrs = true;
+
+ return NULL_TREE;
+}
+
+/* Handle the "btf_type_tag" attribute. */
+
+static tree
+handle_btf_type_tag_attribute (tree *node, tree name, tree args,
+ int flags, bool *no_add_attrs)
+{
+ if (!btf_tag_args_ok (name, args))
+ {
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (*node) == FUNCTION_TYPE || TREE_CODE (*node) == METHOD_TYPE)
+ {
+ warning (OPT_Wattributes,
+ "%qE attribute does not apply to functions", name);
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ /* Ensure a variant type is always created to hold the type_tag,
+ unless ATTR_FLAG_IN_PLACE is set. Same logic as in
+ common_handle_aligned_attribute. */
+ tree decl = NULL_TREE;
+ tree *type = NULL;
+ bool is_type = false;
+
+ if (DECL_P (*node))
+ {
+ decl = *node;
+ type = &TREE_TYPE (decl);
+ is_type = TREE_CODE (*node) == TYPE_DECL;
+ }
+ else if (TYPE_P (*node))
+ type = node, is_type = true;
+
+ if (is_type)
+ {
+ if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ /* OK, modify the type in place. */;
+
+ /* If we have a TYPE_DECL, then copy the type, so that we
+ don't accidentally modify a builtin type. See pushdecl. */
+ else if (decl && TREE_TYPE (decl) != error_mark_node
+ && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
+ {
+ tree tt = TREE_TYPE (decl);
+ *type = build_variant_type_copy (*type);
+ DECL_ORIGINAL_TYPE (decl) = tt;
+ TYPE_NAME (*type) = decl;
+ TREE_USED (*type) = TREE_USED (decl);
+ TREE_TYPE (decl) = *type;
+ }
+ else
+ *type = build_variant_type_copy (*type);
+ }
+
+ return NULL_TREE;
+}
+
/* Handle the "nonstring" variable attribute. */
static tree
@@ -5727,6 +5911,71 @@ handle_access_attribute (tree node[3], tree name, tree args, int flags,
return NULL_TREE;
}
+
+/* This function builds a string which is concatenated to SPEC and returns
+ list of variably bounds corresponding to an array/VLA parameter with
+ type TYPE. The string consists of one dollar symbol for each specified
+ variable bound, one asterisk for each unspecified variable bound,
+ a space for an array of unknown size (only possibly for the outermost),
+ and a zero for a zero-sized array.
+
+ The chainof variable bounds starts with the most significant bound.
+ For example, the TYPE T[2][m][3][n] will produce "$$" and (m, (n, nil)). */
+
+static tree
+build_arg_spec (tree type, std::string *spec)
+{
+ while (POINTER_TYPE_P (type))
+ type = TREE_TYPE (type);
+
+ if (TREE_CODE (type) != ARRAY_TYPE)
+ return NULL_TREE;
+
+ tree list = build_arg_spec (TREE_TYPE (type), spec);
+
+ if (!COMPLETE_TYPE_P (type))
+ {
+ (*spec) += ' ';
+ return list;
+ }
+
+ tree mval = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
+
+ if (!mval)
+ {
+ (*spec) += '0';
+ return list;
+ }
+
+ if (TREE_CODE (mval) == COMPOUND_EXPR
+ && integer_zerop (TREE_OPERAND (mval, 0))
+ && integer_zerop (TREE_OPERAND (mval, 1)))
+ {
+ (*spec) += '*';
+ return list;
+ }
+
+ if (TREE_CODE (mval) == INTEGER_CST)
+ return list;
+
+ /* A variable bound. */
+ (*spec) += '$';
+
+ mval = array_type_nelts_top (type);
+
+ /* Remove NOP_EXPR and SAVE_EXPR to uncover possible PARM_DECLS. */
+ if (TREE_CODE (mval) == NOP_EXPR)
+ mval = TREE_OPERAND (mval, 0);
+ if (TREE_CODE (mval) == SAVE_EXPR)
+ {
+ mval = TREE_OPERAND (mval, 0);
+ if (TREE_CODE (mval) == NOP_EXPR)
+ mval = TREE_OPERAND (mval, 0);
+ }
+
+ return tree_cons (NULL_TREE, mval, list);
+}
+
/* Extract attribute "arg spec" from each FNDECL argument that has it,
build a single attribute access corresponding to all the arguments,
and return the result. SKIP_VOIDPTR set to ignore void* parameters
@@ -5803,15 +6052,16 @@ build_attr_access_from_parms (tree parms, bool skip_voidptr)
argspec = TREE_VALUE (argspec);
/* The attribute arg spec string. */
- tree str = TREE_VALUE (argspec);
- const char *s = TREE_STRING_POINTER (str);
+ const char *s = TREE_STRING_POINTER (TREE_VALUE (argspec));
+ bool static_p = s && (0 == strcmp("static", s));
/* Collect the list of nonnull arguments which use "[static ..]". */
- if (s != NULL && s[0] == '[' && s[1] == 's')
+ if (static_p)
nnlist = tree_cons (NULL_TREE, build_int_cst (integer_type_node,
argpos + 1), nnlist);
- /* Create the attribute access string from the arg spec string,
+ tree argvbs;
+ /* Create the attribute access string from the arg spec data,
optionally followed by position of the VLA bound argument if
it is one. */
{
@@ -5822,21 +6072,52 @@ build_attr_access_from_parms (tree parms, bool skip_voidptr)
specend = 1;
}
- /* Format the access string in place. */
- int len = snprintf (NULL, 0, "%c%u%s",
- attr_access::mode_chars[access_deferred],
- argpos, s);
- spec.resize (specend + len + 1);
- sprintf (&spec[specend], "%c%u%s",
- attr_access::mode_chars[access_deferred],
- argpos, s);
+ spec += attr_access::mode_chars[access_deferred];
+ spec += std::to_string (argpos);
+ spec += '[';
+ tree type = TREE_VALUE (TREE_CHAIN (argspec));
+ argvbs = build_arg_spec (type, &spec);
+
+ /* Postprocess the string to bring it in the format expected
+ by the code handling the access attribute. First, we
+ add 's' if the array was declared as [static ...]. */
+ if (static_p)
+ {
+ size_t send = spec.length();
+
+ if (spec[send - 1] == '[')
+ {
+ spec += 's';
+ }
+ else
+ {
+ /* If there is a symbol, we need to swap the order. */
+ spec += spec[send - 1];
+ spec[send - 1] = 's';
+ }
+ }
+
+ /* If the outermost bound is an integer constant, we need to write
+ the size if it is constant. */
+ if (type && TYPE_DOMAIN (type))
+ {
+ tree mval = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
+ if (mval && TREE_CODE (mval) == INTEGER_CST)
+ {
+ char buf[40];
+ unsigned HOST_WIDE_INT n = tree_to_uhwi (mval) + 1;
+ sprintf (buf, HOST_WIDE_INT_PRINT_UNSIGNED, n);
+ spec += buf;
+ }
+ }
+ spec += ']';
+
/* Trim the trailing NUL. */
- spec.resize (specend + len);
+ spec.resize (spec.length ());
}
/* The (optional) list of expressions denoting the VLA bounds
N in ARGTYPE <arg>[Ni]...[Nj]...[Nk]. */
- tree argvbs = TREE_CHAIN (argspec);
if (argvbs)
{
spec += ',';
@@ -5849,8 +6130,7 @@ build_attr_access_from_parms (tree parms, bool skip_voidptr)
order. */
vblist = tree_cons (NULL_TREE, argvbs, vblist);
- unsigned nelts = 0;
- for (tree vb = argvbs; vb; vb = TREE_CHAIN (vb), ++nelts)
+ for (tree vb = argvbs; vb; vb = TREE_CHAIN (vb))
{
tree bound = TREE_VALUE (vb);
if (const unsigned *psizpos = arg2pos.get (bound))
@@ -6132,10 +6412,25 @@ handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
}
}
- if (get_target_clone_attr_len (args) == -1)
+ int num_defaults = 0;
+ auto_vec<string_slice> versions = get_clone_attr_versions
+ (args,
+ &num_defaults,
+ false);
+
+ for (auto v : versions)
+ targetm.check_target_clone_version
+ (v, &DECL_SOURCE_LOCATION (*node));
+
+ /* Lone target_clones version is always ignored for target attr semantics.
+ Only ignore under target_version semantics if it is a default
+ version. */
+ if (versions.length () == 1
+ && (TARGET_HAS_FMV_TARGET_ATTRIBUTE || num_defaults == 1))
{
- warning (OPT_Wattributes,
- "single %<target_clones%> attribute is ignored");
+ if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
+ warning (OPT_Wattributes,
+ "single %<target_clones%> attribute is ignored");
*no_add_attrs = true;
}
else
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 587d764..3cec729 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pretty-print-markup.h"
#include "gcc-rich-location.h"
#include "gcc-urlifier.h"
+#include "diagnostics/diagnostics-selftests.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
@@ -375,9 +376,10 @@ static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT);
C --std=c17: D_C23 | D_CXXONLY | D_OBJC
C --std=c23: 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
- C++ --std=c++20: D_CONLY | D_OBJC
+ C++ --std=c++98: D_CONLY | D_CXX11 | D_CXX20 | D_CXX26 | D_OBJC
+ C++ --std=c++11: D_CONLY | D_CXX20 | D_CXX26 | D_OBJC
+ C++ --std=c++20: D_CONLY | D_CXX26 | D_OBJC
+ C++ --std=c++26: D_CONLY | D_OBJC
ObjC++ is like C++ except that D_OBJC is not set
If -fno-asm is used, D_ASM is added to the mask. If
@@ -394,6 +396,9 @@ const struct c_common_resword c_common_reswords[] =
{
{ "_Alignas", RID_ALIGNAS, D_CONLY },
{ "_Alignof", RID_ALIGNOF, D_CONLY },
+ { "_Countof", RID_COUNTOF, D_CONLY },
+ { "_Maxof", RID_MAXOF, D_CONLY },
+ { "_Minof", RID_MINOF, D_CONLY },
{ "_Atomic", RID_ATOMIC, D_CONLY },
{ "_BitInt", RID_BITINT, D_CONLY },
{ "_Bool", RID_BOOL, D_CONLY },
@@ -460,7 +465,7 @@ const struct c_common_resword c_common_reswords[] =
{ "__builtin_tgmath", RID_BUILTIN_TGMATH, D_CONLY },
{ "__builtin_offsetof", RID_OFFSETOF, 0 },
{ "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY },
- { "__builtin_c23_va_start", RID_C23_VA_START, D_C23 },
+ { "__builtin_c23_va_start", RID_C23_VA_START, D_C23 | D_CXX26 },
{ "__builtin_va_arg", RID_VA_ARG, 0 },
{ "__complex", RID_COMPLEX, 0 },
{ "__complex__", RID_COMPLEX, 0 },
@@ -1309,6 +1314,7 @@ c_build_vec_convert (location_t loc1, tree expr, location_t loc2, tree type,
if (!gnu_vector_type_p (TREE_TYPE (expr))
|| (!VECTOR_INTEGER_TYPE_P (TREE_TYPE (expr))
+ && !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (expr))
&& !VECTOR_FLOAT_TYPE_P (TREE_TYPE (expr))))
{
if (complain)
@@ -1318,7 +1324,8 @@ c_build_vec_convert (location_t loc1, tree expr, location_t loc2, tree type,
}
if (!gnu_vector_type_p (type)
- || (!VECTOR_INTEGER_TYPE_P (type) && !VECTOR_FLOAT_TYPE_P (type)))
+ || (!VECTOR_INTEGER_TYPE_P (type) && !VECTOR_FLOAT_TYPE_P (type)
+ && !VECTOR_BOOLEAN_TYPE_P (type)))
{
if (complain)
error_at (loc2, "%<__builtin_convertvector%> second argument must "
@@ -3437,20 +3444,41 @@ pointer_int_sum (location_t loc, enum tree_code resultcode,
an overflow error if the constant is negative but INTOP is not. */
&& (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (intop))
|| (TYPE_PRECISION (TREE_TYPE (intop))
- == TYPE_PRECISION (TREE_TYPE (ptrop)))))
- {
- enum tree_code subcode = resultcode;
- tree int_type = TREE_TYPE (intop);
- if (TREE_CODE (intop) == MINUS_EXPR)
- subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR);
- /* Convert both subexpression types to the type of intop,
- because weird cases involving pointer arithmetic
- can result in a sum or difference with different type args. */
- ptrop = build_binary_op (EXPR_LOCATION (TREE_OPERAND (intop, 1)),
- subcode, ptrop,
- convert (int_type, TREE_OPERAND (intop, 1)),
- true);
- intop = convert (int_type, TREE_OPERAND (intop, 0));
+ == TYPE_PRECISION (TREE_TYPE (ptrop))))
+ && TYPE_PRECISION (TREE_TYPE (intop)) <= TYPE_PRECISION (sizetype))
+ {
+ tree intop0 = TREE_OPERAND (intop, 0);
+ tree intop1 = TREE_OPERAND (intop, 1);
+ if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
+ || TYPE_UNSIGNED (TREE_TYPE (intop)) != TYPE_UNSIGNED (sizetype))
+ {
+ tree optype = c_common_type_for_size (TYPE_PRECISION (sizetype),
+ TYPE_UNSIGNED (sizetype));
+ intop0 = convert (optype, intop0);
+ intop1 = convert (optype, intop1);
+ }
+ tree t = fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (intop0), intop0,
+ convert (TREE_TYPE (intop0), size_exp));
+ intop0 = convert (sizetype, t);
+ if (TREE_OVERFLOW_P (intop0) && !TREE_OVERFLOW (t))
+ intop0 = wide_int_to_tree (TREE_TYPE (intop0), wi::to_wide (intop0));
+ t = fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (intop1), intop1,
+ convert (TREE_TYPE (intop1), size_exp));
+ intop1 = convert (sizetype, t);
+ if (TREE_OVERFLOW_P (intop1) && !TREE_OVERFLOW (t))
+ intop1 = wide_int_to_tree (TREE_TYPE (intop1), wi::to_wide (intop1));
+ intop = build_binary_op (EXPR_LOCATION (intop), TREE_CODE (intop),
+ intop0, intop1, true);
+
+ /* Create the sum or difference. */
+ if (resultcode == MINUS_EXPR)
+ intop = fold_build1_loc (loc, NEGATE_EXPR, sizetype, intop);
+
+ ret = fold_build_pointer_plus_loc (loc, ptrop, intop);
+
+ fold_undefer_and_ignore_overflow_warnings ();
+
+ return ret;
}
/* Convert the integer argument to a type the same size as sizetype
@@ -3917,14 +3945,40 @@ c_common_get_alias_set (tree t)
/* The C standard specifically allows aliasing between signed and
unsigned variants of the same type. We treat the signed
variant as canonical. */
- if ((TREE_CODE (t) == INTEGER_TYPE || TREE_CODE (t) == BITINT_TYPE)
- && TYPE_UNSIGNED (t))
- {
- tree t1 = c_common_signed_type (t);
-
- /* t1 == t can happen for boolean nodes which are always unsigned. */
- if (t1 != t)
- return get_alias_set (t1);
+ if (TREE_CODE (t) == INTEGER_TYPE || TREE_CODE (t) == BITINT_TYPE)
+ {
+ /* For normal INTEGER_TYPEs (except ones built by
+ build_nonstandard_integer_type), both signed and unsigned variants
+ of the type are always reachable from GTY roots, so just calling
+ get_alias_set on the signed type is ok. For BITINT_TYPE and
+ non-standard INTEGER_TYPEs, only unsigned could be used and the
+ corresponding signed type could be created on demand and garbage
+ collected as unused, so the alias set of unsigned type could keep
+ changing.
+ Avoid that by remembering the signed type alias set in
+ TYPE_ALIAS_SET and also when being asked about !TYPE_UNSIGNED
+ check if there isn't a corresponding unsigned type with
+ TYPE_ALIAS_SET_KNOWN_P. */
+ if (TYPE_UNSIGNED (t))
+ {
+ /* There is no signed _BitInt(1). */
+ if (TREE_CODE (t) == BITINT_TYPE && TYPE_PRECISION (t) == 1)
+ return -1;
+ tree t1 = c_common_signed_type (t);
+ gcc_checking_assert (t != t1);
+ TYPE_ALIAS_SET (t) = get_alias_set (t1);
+ return TYPE_ALIAS_SET (t);
+ }
+ else
+ {
+ tree t1 = c_common_unsigned_type (t);
+ gcc_checking_assert (t != t1);
+ if (TYPE_ALIAS_SET_KNOWN_P (t1))
+ {
+ TYPE_ALIAS_SET (t) = TYPE_ALIAS_SET (t1);
+ return TYPE_ALIAS_SET (t);
+ }
+ }
}
return -1;
@@ -4080,6 +4134,79 @@ c_alignof_expr (location_t loc, tree expr)
return fold_convert_loc (loc, size_type_node, t);
}
+
+/* Implement the _Countof keyword:
+ Return the number of elements of an array. */
+
+tree
+c_countof_type (location_t loc, tree type)
+{
+ enum tree_code type_code;
+ tree value;
+
+ type_code = TREE_CODE (type);
+ if (type_code != ARRAY_TYPE)
+ {
+ error_at (loc, "invalid application of %<_Countof%> to type %qT", type);
+ return error_mark_node;
+ }
+ if (!COMPLETE_TYPE_P (type))
+ {
+ error_at (loc,
+ "invalid application of %<_Countof%> to incomplete type %qT",
+ type);
+ return error_mark_node;
+ }
+
+ value = array_type_nelts_top (type);
+ /* VALUE will have the middle-end integer type sizetype.
+ However, we should really return a value of type `size_t',
+ which is just a typedef for an ordinary integer type. */
+ value = fold_convert_loc (loc, size_type_node, value);
+ return value;
+}
+
+/* Implement the _Maxof operator:
+ Return the maximum representable value of an integer type. */
+
+tree
+c_maxof_type (location_t loc, tree type)
+{
+ if (!INTEGRAL_TYPE_P (type))
+ {
+ error_at (loc, "invalid application of %<_Maxof%> to type %qT", type);
+ return error_mark_node;
+ }
+ if (!COMPLETE_TYPE_P (type))
+ {
+ error_at (loc, "invalid application of %<_Maxof%> to incomplete type %qT",
+ type);
+ return error_mark_node;
+ }
+
+ return TYPE_MAX_VALUE (type);
+}
+
+/* Implement the _Minof operator:
+ Return the minimum representable value of an integer type. */
+
+tree
+c_minof_type (location_t loc, tree type)
+{
+ if (!INTEGRAL_TYPE_P (type))
+ {
+ error_at (loc, "invalid application of %<_Minof%> to type %qT", type);
+ return error_mark_node;
+ }
+ if (!COMPLETE_TYPE_P (type))
+ {
+ error_at (loc, "invalid application of %<_Minof%> to incomplete type %qT",
+ type);
+ return error_mark_node;
+ }
+
+ return TYPE_MIN_VALUE (type);
+}
/* Handle C and C++ default attributes. */
@@ -5723,8 +5850,8 @@ struct nonnull_arg_ctx
/* The function whose arguments are being checked and its type (used
for calls through function pointers). */
const_tree fndecl, fntype;
- /* For nonnull_if_nonzero, index of the other argument. */
- unsigned HOST_WIDE_INT other;
+ /* For nonnull_if_nonzero, index of the other arguments. */
+ unsigned HOST_WIDE_INT other1, other2;
/* True if a warning has been issued. */
bool warned_p;
};
@@ -5792,6 +5919,7 @@ check_function_nonnull (nonnull_arg_ctx &ctx, int nargs, tree *argarray)
check_function_arguments_recurse (check_nonnull_arg, &ctx,
argarray[i], i + 1,
OPT_Wnonnull);
+ a = NULL_TREE;
}
}
if (a == NULL_TREE)
@@ -5803,17 +5931,25 @@ check_function_nonnull (nonnull_arg_ctx &ctx, int nargs, tree *argarray)
unsigned int idx = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1;
unsigned int idx2
= TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1;
+ unsigned int idx3 = idx2;
+ if (tree chain2 = TREE_CHAIN (TREE_CHAIN (args)))
+ idx3 = TREE_INT_CST_LOW (TREE_VALUE (chain2)) - 1;
if (idx < (unsigned) nargs - firstarg
&& idx2 < (unsigned) nargs - firstarg
+ && idx3 < (unsigned) nargs - firstarg
&& INTEGRAL_TYPE_P (TREE_TYPE (argarray[firstarg + idx2]))
- && integer_nonzerop (argarray[firstarg + idx2]))
+ && integer_nonzerop (argarray[firstarg + idx2])
+ && INTEGRAL_TYPE_P (TREE_TYPE (argarray[firstarg + idx3]))
+ && integer_nonzerop (argarray[firstarg + idx3]))
{
- ctx.other = firstarg + idx2 + 1;
+ ctx.other1 = firstarg + idx2 + 1;
+ ctx.other2 = firstarg + idx3 + 1;
check_function_arguments_recurse (check_nonnull_arg, &ctx,
argarray[firstarg + idx],
firstarg + idx + 1,
OPT_Wnonnull);
- ctx.other = 0;
+ ctx.other1 = 0;
+ ctx.other2 = 0;
}
}
return ctx.warned_p;
@@ -5997,14 +6133,25 @@ check_nonnull_arg (void *ctx, tree param, unsigned HOST_WIDE_INT param_num)
}
else
{
- if (pctx->other)
+ if (pctx->other1 && pctx->other2 != pctx->other1)
+ warned = warning_at (loc, OPT_Wnonnull,
+ "argument %u null where non-null expected "
+ "because arguments %u and %u are nonzero",
+ (unsigned) param_num,
+ TREE_CODE (pctx->fntype) == METHOD_TYPE
+ ? (unsigned) pctx->other1 - 1
+ : (unsigned) pctx->other1,
+ TREE_CODE (pctx->fntype) == METHOD_TYPE
+ ? (unsigned) pctx->other2 - 1
+ : (unsigned) pctx->other2);
+ else if (pctx->other1)
warned = warning_at (loc, OPT_Wnonnull,
"argument %u null where non-null expected "
"because argument %u is nonzero",
(unsigned) param_num,
TREE_CODE (pctx->fntype) == METHOD_TYPE
- ? (unsigned) pctx->other - 1
- : (unsigned) pctx->other);
+ ? (unsigned) pctx->other1 - 1
+ : (unsigned) pctx->other1);
else
warned = warning_at (loc, OPT_Wnonnull,
"argument %u null where non-null expected",
@@ -6013,7 +6160,7 @@ check_nonnull_arg (void *ctx, tree param, unsigned HOST_WIDE_INT param_num)
inform (DECL_SOURCE_LOCATION (pctx->fndecl),
"in a call to function %qD declared %qs",
pctx->fndecl,
- pctx->other ? "nonnull_if_nonzero" : "nonnull");
+ pctx->other1 ? "nonnull_if_nonzero" : "nonnull");
}
if (warned)
@@ -6269,7 +6416,7 @@ check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype,
to do this if format checking is enabled. */
if (warn_nonnull)
{
- nonnull_arg_ctx ctx = { loc, fndecl, fntype, 0, false };
+ nonnull_arg_ctx ctx = { loc, fndecl, fntype, 0, 0, false };
warned_p = check_function_nonnull (ctx, nargs, argarray);
}
@@ -6958,7 +7105,7 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
/* Return the gcc option code associated with the reason for a cpp
message, or 0 if none. */
-static diagnostic_option_id
+static diagnostics::option_id
c_option_controlling_cpp_diagnostic (enum cpp_warning_reason reason)
{
const struct cpp_reason_option_codes_t *entry;
@@ -7000,8 +7147,8 @@ c_cpp_diagnostic (cpp_reader *pfile ATTRIBUTE_UNUSED,
rich_location *richloc,
const char *msg, va_list *ap)
{
- diagnostic_info diagnostic;
- diagnostic_t dlevel;
+ diagnostics::diagnostic_info diagnostic;
+ enum diagnostics::kind dlevel;
bool save_warn_system_headers = global_dc->m_warn_system_headers;
bool ret;
@@ -7015,24 +7162,24 @@ c_cpp_diagnostic (cpp_reader *pfile ATTRIBUTE_UNUSED,
case CPP_DL_WARNING:
if (flag_no_output)
return false;
- dlevel = DK_WARNING;
+ dlevel = diagnostics::kind::warning;
break;
case CPP_DL_PEDWARN:
if (flag_no_output && !flag_pedantic_errors)
return false;
- dlevel = DK_PEDWARN;
+ dlevel = diagnostics::kind::pedwarn;
break;
case CPP_DL_ERROR:
- dlevel = DK_ERROR;
+ dlevel = diagnostics::kind::error;
break;
case CPP_DL_ICE:
- dlevel = DK_ICE;
+ dlevel = diagnostics::kind::ice;
break;
case CPP_DL_NOTE:
- dlevel = DK_NOTE;
+ dlevel = diagnostics::kind::note;
break;
case CPP_DL_FATAL:
- dlevel = DK_FATAL;
+ dlevel = diagnostics::kind::fatal;
break;
default:
gcc_unreachable ();
@@ -9896,8 +10043,11 @@ c_family_tests (void)
c_indentation_cc_tests ();
c_pretty_print_cc_tests ();
c_spellcheck_cc_tests ();
- c_diagnostic_cc_tests ();
c_opt_problem_cc_tests ();
+
+ /* According to https://gcc.gnu.org/pipermail/gcc/2021-November/237703.html
+ this has some language-specific assumptions, so we run it here. */
+ diagnostics::selftest::context_cc_tests ();
}
} // namespace selftest
@@ -9979,7 +10129,7 @@ try_to_locate_new_include_insertion_point (const char *file, location_t loc)
return UNKNOWN_LOCATION;
/* The "start_location" is column 0, meaning "the whole line".
- rich_location and edit_context can't cope with this, so use
+ rich_location and diagnostics::changes can't cope with this, so use
column 1 instead. */
location_t col_0 = ord_map_for_insertion->start_location;
return linemap_position_for_loc_and_offset (line_table, col_0, 1);
@@ -10043,7 +10193,7 @@ maybe_add_include_fixit (rich_location *richloc, const char *header,
richloc->add_fixit_insert_before (include_insert_loc, text);
free (text);
- if (override_location && global_dc->m_source_printing.enabled)
+ if (override_location && global_dc->get_source_printing_options ().enabled)
{
/* Replace the primary location with that of the insertion point for the
fix-it hint.
@@ -10224,6 +10374,7 @@ braced_list_to_string (tree type, tree ctor, bool member)
j = i - start;
else
j -= start;
+ value = copy_node (value);
RAW_DATA_POINTER (value) -= start;
RAW_DATA_LENGTH (value) += start + end;
i += end;
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index cf22282..9b1f034 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -50,6 +50,15 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", tcc_expression, 1)
number. */
DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
+/* Represents a 'countof' expression. */
+DEFTREECODE (COUNTOF_EXPR, "countof_expr", tcc_expression, 1)
+
+/* Represents a 'maxof' expression. */
+DEFTREECODE (MAXOF_EXPR, "maxof_expr", tcc_expression, 1)
+
+/* Represents a 'minof' expression. */
+DEFTREECODE (MINOF_EXPR, "minof_expr", tcc_expression, 1)
+
/* Represents a 'sizeof' expression during C++ template expansion,
or for the purpose of -Wsizeof-pointer-memaccess warning. */
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index ea6c297..6a92bd6 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -105,6 +105,7 @@ enum rid
/* C extensions */
RID_ASM, RID_TYPEOF, RID_TYPEOF_UNQUAL, RID_ALIGNOF, RID_ATTRIBUTE,
+ RID_COUNTOF, RID_MAXOF, RID_MINOF,
RID_C23_VA_START, RID_VA_ARG,
RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR,
RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE,
@@ -447,6 +448,7 @@ extern machine_mode c_default_pointer_mode;
#define D_CXX20 0x8000 /* In C++, C++20 only. */
#define D_CXX_COROUTINES 0x10000 /* In C++, only with coroutines. */
#define D_CXX_MODULES 0x20000 /* In C++, only with modules. */
+#define D_CXX26 0x40000 /* In C++, C++26 only. */
#define D_CXX_CONCEPTS_FLAGS D_CXXONLY | D_CXX_CONCEPTS
#define D_CXX_CHAR8_T_FLAGS D_CXXONLY | D_CXX_CHAR8_T
@@ -746,7 +748,7 @@ enum cxx_dialect {
cxx26
};
-/* The C++ dialect being used. C++98 is the default. */
+/* The C++ dialect being used. C++17 is the default. */
extern enum cxx_dialect cxx_dialect;
/* Maximum template instantiation depth. This limit is rather
@@ -890,6 +892,9 @@ extern tree c_common_truthvalue_conversion (location_t, tree);
extern void c_apply_type_quals_to_decl (int, tree);
extern tree c_sizeof_or_alignof_type (location_t, tree, bool, bool, int);
extern tree c_alignof_expr (location_t, tree);
+extern tree c_countof_type (location_t, tree);
+extern tree c_maxof_type (location_t, tree);
+extern tree c_minof_type (location_t, tree);
/* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error (rich_location *, enum tree_code, tree, tree);
@@ -977,7 +982,7 @@ extern tree build_va_arg (location_t, tree, tree);
extern const unsigned int c_family_lang_mask;
extern unsigned int c_common_option_lang_mask (void);
-extern void c_common_diagnostics_set_defaults (diagnostic_context *);
+extern void c_common_diagnostics_set_defaults (diagnostics::context *);
extern bool c_common_complain_wrong_lang_p (const struct cl_option *);
extern void c_common_init_options_struct (struct gcc_options *);
extern void c_common_init_options (unsigned int, struct cl_decoded_option *);
@@ -1263,7 +1268,7 @@ extern void c_stddef_cpp_builtins (void);
extern void fe_file_change (const line_map_ordinary *);
extern void c_parse_error (const char *, enum cpp_ttype, tree, unsigned char,
rich_location *richloc);
-extern diagnostic_option_id get_option_for_builtin_define (const char *macro_name);
+extern diagnostics::option_id get_option_for_builtin_define (const char *macro_name);
/* In c-ppoutput.cc */
extern void init_pp_output (FILE *);
@@ -1301,10 +1306,12 @@ enum c_omp_region_type
C_ORT_TARGET = 1 << 3,
C_ORT_EXIT_DATA = 1 << 4,
C_ORT_INTEROP = 1 << 5,
+ C_ORT_DECLARE_MAPPER = 1 << 6,
C_ORT_OMP_DECLARE_SIMD = C_ORT_OMP | C_ORT_DECLARE_SIMD,
C_ORT_OMP_TARGET = C_ORT_OMP | C_ORT_TARGET,
C_ORT_OMP_EXIT_DATA = C_ORT_OMP | C_ORT_EXIT_DATA,
C_ORT_OMP_INTEROP = C_ORT_OMP | C_ORT_INTEROP,
+ C_ORT_OMP_DECLARE_MAPPER = C_ORT_OMP | C_ORT_DECLARE_MAPPER,
C_ORT_ACC_TARGET = C_ORT_ACC | C_ORT_TARGET
};
@@ -1343,6 +1350,9 @@ extern enum omp_clause_defaultmap_kind c_omp_predetermined_mapping (tree);
extern tree c_omp_check_context_selector (location_t, tree);
extern void c_omp_mark_declare_variant (location_t, tree, tree);
extern void c_omp_adjust_map_clauses (tree, bool);
+template<typename T> struct omp_mapper_list;
+extern void c_omp_find_nested_mappers (struct omp_mapper_list<tree> *, tree);
+extern tree c_omp_instantiate_mappers (tree);
namespace omp_addr_tokenizer { struct omp_addr_token; }
typedef omp_addr_tokenizer::omp_addr_token omp_addr_token;
@@ -1616,7 +1626,7 @@ extern void c_do_switch_warnings (splay_tree, location_t, tree, tree, bool);
extern void warn_for_omitted_condop (location_t, tree);
extern bool warn_for_restrict (unsigned, tree *, unsigned);
extern void warn_for_address_of_packed_member (tree, tree);
-extern void warn_parm_array_mismatch (location_t, tree, tree);
+extern void warn_parms_array_mismatch (location_t, tree, tree);
extern void maybe_warn_sizeof_array_div (location_t, tree, tree, tree, tree);
extern void do_warn_array_compare (location_t, tree_code, tree, tree);
@@ -1706,7 +1716,7 @@ extern enum flt_eval_method
excess_precision_mode_join (enum flt_eval_method, enum flt_eval_method);
extern int c_flt_eval_method (bool ts18661_p);
-extern void add_no_sanitize_value (tree node, unsigned int flags);
+extern void add_no_sanitize_value (tree node, sanitize_code_type flags);
extern void maybe_add_include_fixit (rich_location *, const char *, bool);
extern void maybe_suggest_missing_token_insertion (rich_location *richloc,
@@ -1722,7 +1732,6 @@ extern tree braced_lists_to_strings (tree, tree);
namespace selftest {
/* Declarations for specific families of tests within c-family,
by source file, in alphabetical order. */
- extern void c_diagnostic_cc_tests (void);
extern void c_format_cc_tests (void);
extern void c_indentation_cc_tests (void);
extern void c_opt_problem_cc_tests (void);
diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index 4589ee4..eac6969 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -913,23 +913,42 @@ c_cpp_builtins (cpp_reader *pfile)
/* encoding definitions used by users and libraries */
builtin_define_with_value ("__GNUC_EXECUTION_CHARSET_NAME",
- cpp_get_narrow_charset_name (pfile), 1);
+ cpp_get_narrow_charset_name (pfile), 1);
builtin_define_with_value ("__GNUC_WIDE_EXECUTION_CHARSET_NAME",
- cpp_get_wide_charset_name (pfile), 1);
-
+ cpp_get_wide_charset_name (pfile), 1);
if (c_dialect_cxx ())
- {
- int major;
- parse_basever (&major, NULL, NULL);
- cpp_define_formatted (pfile, "__GNUG__=%d", major);
- }
+ {
+ int major;
+ parse_basever (&major, NULL, NULL);
+ cpp_define_formatted (pfile, "__GNUG__=%d", major);
+ }
/* For stddef.h. They require macros defined in c-common.cc. */
c_stddef_cpp_builtins ();
+ /* Variant of cpp_define which arranges for diagnostics on user #define
+ or #undef of the macros. */
+ auto cpp_define_warn = [] (cpp_reader *pfile, const char *def)
+ {
+ const char *end = strchr (def, '=');
+ cpp_define (pfile, def);
+ cpp_warn (pfile, def, end ? end - def : strlen (def));
+ };
+
if (c_dialect_cxx ())
{
+ /* Treat all cpp_define calls in this block for macros starting
+ with __cpp_ (for C++20 and later) or __STDCPP_ as cpp_define_warn. */
+ auto cpp_define = [=] (cpp_reader *pfile, const char *def)
+ {
+ if ((cxx_dialect >= cxx20 && startswith (def, "__cpp_"))
+ || startswith (def, "__STDCPP_"))
+ cpp_define_warn (pfile, def);
+ else
+ ::cpp_define (pfile, def);
+ };
+
if (flag_weak && SUPPORTS_ONE_ONLY)
cpp_define (pfile, "__GXX_WEAK__=1");
else
@@ -1087,52 +1106,78 @@ c_cpp_builtins (cpp_reader *pfile)
{
/* Set feature test macros for C++26. */
cpp_define (pfile, "__cpp_constexpr=202406L");
+ cpp_define (pfile, "__cpp_constexpr_exceptions=202411L");
cpp_define (pfile, "__cpp_static_assert=202306L");
cpp_define (pfile, "__cpp_placeholder_variables=202306L");
- cpp_define (pfile, "__cpp_structured_bindings=202403L");
+ cpp_define (pfile, "__cpp_structured_bindings=202411L");
cpp_define (pfile, "__cpp_deleted_function=202403L");
cpp_define (pfile, "__cpp_variadic_friend=202403L");
cpp_define (pfile, "__cpp_pack_indexing=202311L");
cpp_define (pfile, "__cpp_pp_embed=202502L");
+ cpp_define (pfile, "__cpp_constexpr_virtual_inheritance=202506L");
+ cpp_define (pfile, "__cpp_expansion_statements=202506L");
}
if (flag_concepts && cxx_dialect > cxx14)
cpp_define (pfile, "__cpp_concepts=202002L");
+ else if (cxx_dialect >= cxx20)
+ cpp_warn (pfile, "__cpp_concepts");
if (flag_contracts)
{
cpp_define (pfile, "__cpp_contracts=201906L");
cpp_define (pfile, "__cpp_contracts_literal_semantics=201906L");
cpp_define (pfile, "__cpp_contracts_roles=201906L");
}
+ else if (cxx_dialect >= cxx26)
+ cpp_warn (pfile, "__cpp_contracts");
if (flag_modules)
/* The std-defined value is 201907L, but I don't think we can
claim victory yet. 201810 is the p1103 date. */
cpp_define (pfile, "__cpp_modules=201810L");
+ else if (cxx_dialect >= cxx20)
+ cpp_warn (pfile, "__cpp_modules");
if (flag_coroutines)
cpp_define (pfile, "__cpp_impl_coroutine=201902L"); /* n4861, DIS */
+ else if (cxx_dialect >= cxx20)
+ cpp_warn (pfile, "__cpp_impl_coroutine");
if (flag_tm)
/* Use a value smaller than the 201505 specified in
the TS, since we don't yet support atomic_cancel. */
cpp_define (pfile, "__cpp_transactional_memory=201500L");
if (flag_sized_deallocation)
cpp_define (pfile, "__cpp_sized_deallocation=201309L");
+ else if (cxx_dialect >= cxx20)
+ cpp_warn (pfile, "__cpp_sized_deallocation");
if (aligned_new_threshold)
{
cpp_define (pfile, "__cpp_aligned_new=201606L");
cpp_define_formatted (pfile, "__STDCPP_DEFAULT_NEW_ALIGNMENT__=%d",
aligned_new_threshold);
}
+ else if (cxx_dialect >= cxx20)
+ cpp_warn (pfile, "__cpp_aligned_new");
+ if (cxx_dialect >= cxx17)
+ cpp_warn (pfile, "__STDCPP_DEFAULT_NEW_ALIGNMENT__");
if (flag_new_ttp)
cpp_define (pfile, "__cpp_template_template_args=201611L");
+ else if (cxx_dialect >= cxx20)
+ cpp_warn (pfile, "__cpp_template_template_args");
if (flag_threadsafe_statics)
cpp_define (pfile, "__cpp_threadsafe_static_init=200806L");
+ else if (cxx_dialect >= cxx20)
+ cpp_warn (pfile, "__cpp_threadsafe_static_init");
if (flag_char8_t)
cpp_define (pfile, "__cpp_char8_t=202207L");
+ else if (cxx_dialect >= cxx20)
+ cpp_warn (pfile, "__cpp_char8_t");
#ifndef THREAD_MODEL_SPEC
/* Targets that define THREAD_MODEL_SPEC need to define
__STDCPP_THREADS__ in their config/XXX/XXX-c.c themselves. */
if (cxx_dialect >= cxx11 && strcmp (thread_model, "single") != 0)
cpp_define (pfile, "__STDCPP_THREADS__=1");
+ else
#endif
+ if (cxx_dialect >= cxx11)
+ cpp_warn (pfile, "__STDCPP_THREADS__");
if (flag_implicit_constexpr)
cpp_define (pfile, "__cpp_implicit_constexpr=20211111L");
}
@@ -1281,16 +1326,22 @@ c_cpp_builtins (cpp_reader *pfile)
for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
{
- if (FLOATN_NX_TYPE_NODE (i) == NULL_TREE)
- continue;
if (c_dialect_cxx ()
&& cxx_dialect > cxx20
&& !floatn_nx_types[i].extended)
{
char name[sizeof ("__STDCPP_FLOAT128_T__=1")];
+ if (FLOATN_NX_TYPE_NODE (i) == NULL_TREE)
+ {
+ sprintf (name, "__STDCPP_FLOAT%d_T__", floatn_nx_types[i].n);
+ cpp_warn (pfile, name);
+ continue;
+ }
sprintf (name, "__STDCPP_FLOAT%d_T__=1", floatn_nx_types[i].n);
- cpp_define (pfile, name);
+ cpp_define_warn (pfile, name);
}
+ else if (FLOATN_NX_TYPE_NODE (i) == NULL_TREE)
+ continue;
char prefix[20], csuffix[20];
sprintf (prefix, "FLT%d%s", floatn_nx_types[i].n,
floatn_nx_types[i].extended ? "X" : "");
@@ -1302,10 +1353,12 @@ c_cpp_builtins (cpp_reader *pfile)
if (bfloat16_type_node)
{
if (c_dialect_cxx () && cxx_dialect > cxx20)
- cpp_define (pfile, "__STDCPP_BFLOAT16_T__=1");
+ cpp_define_warn (pfile, "__STDCPP_BFLOAT16_T__=1");
builtin_define_float_constants ("BFLT16", "BF16", "%s",
"BF16", bfloat16_type_node);
}
+ else if (cxx_dialect >= cxx23)
+ cpp_warn (pfile, "__STDCPP_BFLOAT16_T__");
/* For float.h. */
if (targetm.decimal_float_supported_p ())
@@ -1678,7 +1731,7 @@ c_cpp_builtins (cpp_reader *pfile)
/* Given NAME, return the command-line option that would make it be
a builtin define, or 0 if unrecognized. */
-diagnostic_option_id
+diagnostics::option_id
get_option_for_builtin_define (const char *name)
{
if (!strcmp (name, "_OPENACC"))
diff --git a/gcc/c-family/c-format.cc b/gcc/c-family/c-format.cc
index 211d20d..bf144d0 100644
--- a/gcc/c-family/c-format.cc
+++ b/gcc/c-family/c-format.cc
@@ -32,7 +32,8 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "substring-locations.h"
#include "selftest.h"
-#include "selftest-diagnostic.h"
+#include "diagnostics/selftest-context.h"
+#include "diagnostics/file-cache.h"
#include "builtins.h"
#include "attribs.h"
#include "c-family/c-type-mismatch.h"
@@ -70,6 +71,7 @@ static GTY(()) tree local_event_ptr_node;
static GTY(()) tree local_pp_element_ptr_node;
static GTY(()) tree local_gimple_ptr_node;
static GTY(()) tree local_cgraph_node_ptr_node;
+static GTY(()) tree local_string_slice_node;
static GTY(()) tree locus;
static bool decode_format_attr (const_tree, tree, tree, function_format_info *,
@@ -770,6 +772,7 @@ static const format_char_info asm_fprintf_char_table[] =
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, \
{ "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "//cR", NULL }, \
{ "@", 1, STD_C89, { T_EVENT_PTR, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, \
+ { "B", 1, STD_C89, { T_STRING_SLICE, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
{ "e", 1, STD_C89, { T_PP_ELEMENT_PTR, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, \
{ "<", 0, STD_C89, NOARGUMENTS, "", "<", NULL }, \
{ ">", 0, STD_C89, NOARGUMENTS, "", ">", NULL }, \
@@ -2124,7 +2127,7 @@ flag_chars_t::validate (const format_kind_info *fki,
{
format_warning_at_char (format_string_loc, format_string_cst,
format_chars - orig_format_chars - 1,
- OPT_Wformat_,
+ OPT_Wformat_diag,
"%s used within a quoted sequence",
_(s->name));
}
@@ -2137,7 +2140,7 @@ flag_chars_t::validate (const format_kind_info *fki,
{
format_warning_at_char (format_string_loc, format_string_cst,
format_chars - orig_format_chars,
- OPT_Wformat_,
+ OPT_Wformat_diag,
"%qc conversion used unquoted",
format_char);
}
@@ -4632,7 +4635,7 @@ get_corrected_substring (const substring_loc &fmt_loc,
if (caret.column > finish.column)
return NULL;
- char_span line
+ diagnostics::char_span line
= global_dc->get_file_cache ().get_source_line (start.file, start.line);
if (!line)
return NULL;
@@ -4644,7 +4647,8 @@ get_corrected_substring (const substring_loc &fmt_loc,
specification, up to the (but not including) the length modifier.
In the above example, this would be "%-+*.*". */
int length_up_to_type = caret.column - start.column;
- char_span prefix_span = line.subspan (start.column - 1, length_up_to_type);
+ diagnostics::char_span prefix_span
+ = line.subspan (start.column - 1, length_up_to_type);
char *prefix = prefix_span.xstrdup ();
/* Now attempt to generate a suggestion for the rest of the specification
@@ -5211,6 +5215,11 @@ init_dynamic_diag_info (void)
|| local_cgraph_node_ptr_node == void_type_node)
local_cgraph_node_ptr_node = get_named_type ("cgraph_node");
+ /* Similar to the above but for string_slice*. */
+ if (!local_string_slice_node
+ || local_string_slice_node == void_type_node)
+ local_string_slice_node = get_named_type ("string_slice");
+
/* Similar to the above but for diagnostic_event_id_t*. */
if (!local_event_ptr_node
|| local_event_ptr_node == void_type_node)
@@ -5577,10 +5586,12 @@ test_type_mismatch_range_labels ()
gcc_rich_location richloc (fmt, &fmt_label, nullptr);
richloc.add_range (param, SHOW_RANGE_WITHOUT_CARET, &param_label);
- test_diagnostic_context dc;
+ diagnostics::selftest::test_context dc;
diagnostic_show_locus (&dc,
- dc.m_source_printing,
- &richloc, DK_ERROR, dc.get_reference_printer ());
+ dc.get_source_printing_options (),
+ &richloc,
+ diagnostics::kind::error,
+ dc.get_reference_printer ());
if (c_dialect_cxx ())
/* "char*", without a space. */
ASSERT_STREQ (" printf (\"msg: %i\\n\", msg);\n"
diff --git a/gcc/c-family/c-format.h b/gcc/c-family/c-format.h
index 323338c..d44d386 100644
--- a/gcc/c-family/c-format.h
+++ b/gcc/c-family/c-format.h
@@ -317,6 +317,7 @@ struct format_kind_info
#define T89_G { STD_C89, NULL, &local_gimple_ptr_node }
#define T_CGRAPH_NODE { STD_C89, NULL, &local_cgraph_node_ptr_node }
#define T_EVENT_PTR { STD_C89, NULL, &local_event_ptr_node }
+#define T_STRING_SLICE { STD_C89, NULL, &local_string_slice_node }
#define T_PP_ELEMENT_PTR { STD_C89, NULL, &local_pp_element_ptr_node }
#define T89_T { STD_C89, NULL, &local_tree_type_node }
#define T89_V { STD_C89, NULL, T_V }
diff --git a/gcc/c-family/c-gimplify.cc b/gcc/c-family/c-gimplify.cc
index c6fb764..2249c10 100644
--- a/gcc/c-family/c-gimplify.cc
+++ b/gcc/c-family/c-gimplify.cc
@@ -66,6 +66,19 @@ along with GCC; see the file COPYING3. If not see
walk back up, we check that they fit our constraints, and copy them
into temporaries if not. */
+
+/* Check whether TP is an address computation whose base is a call to
+ .ACCESS_WITH_SIZE. */
+
+static bool
+is_address_with_access_with_size (tree tp)
+{
+ if (TREE_CODE (tp) == POINTER_PLUS_EXPR
+ && is_access_with_size_p (TREE_OPERAND (tp, 0)))
+ return true;
+ return false;
+}
+
/* Callback for c_genericize. */
static tree
@@ -121,6 +134,20 @@ ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
walk_tree (&TREE_OPERAND (*tp, 1), ubsan_walk_array_refs_r, pset, pset);
walk_tree (&TREE_OPERAND (*tp, 0), ubsan_walk_array_refs_r, pset, pset);
}
+ else if (TREE_CODE (*tp) == INDIRECT_REF
+ && is_address_with_access_with_size (TREE_OPERAND (*tp, 0)))
+ {
+ ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), false);
+ /* Make sure ubsan_maybe_instrument_array_ref is not called again on
+ the POINTER_PLUS_EXPR, so ensure it is not walked again and walk
+ its subtrees manually. */
+ tree aref = TREE_OPERAND (*tp, 0);
+ pset->add (aref);
+ *walk_subtrees = 0;
+ walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
+ }
+ else if (is_address_with_access_with_size (*tp))
+ ubsan_maybe_instrument_array_ref (tp, true);
return NULL_TREE;
}
@@ -1009,7 +1036,14 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
&& call_expr_nargs (*expr_p) == 2
&& TREE_CODE (CALL_EXPR_ARG (*expr_p, 1)) != INTEGER_CST)
{
- tree a = save_expr (CALL_EXPR_ARG (*expr_p, 0));
+ tree a = CALL_EXPR_ARG (*expr_p, 0);
+ if (gimplify_expr (&a, pre_p, post_p, is_gimple_val, fb_rvalue)
+ == GS_ERROR)
+ return GS_ERROR;
+ tree b = CALL_EXPR_ARG (*expr_p, 1);
+ if (gimplify_expr (&b, pre_p, post_p, is_gimple_val, fb_rvalue)
+ == GS_ERROR)
+ return GS_ERROR;
tree c = build_call_expr_loc (EXPR_LOCATION (*expr_p),
fndecl, 1, a);
*expr_p = build3_loc (EXPR_LOCATION (*expr_p), COND_EXPR,
@@ -1017,7 +1051,7 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
build2_loc (EXPR_LOCATION (*expr_p),
NE_EXPR, boolean_type_node, a,
build_zero_cst (TREE_TYPE (a))),
- c, CALL_EXPR_ARG (*expr_p, 1));
+ c, b);
return GS_OK;
}
break;
diff --git a/gcc/c-family/c-indentation.cc b/gcc/c-family/c-indentation.cc
index 2e8261d..d378464 100644
--- a/gcc/c-family/c-indentation.cc
+++ b/gcc/c-family/c-indentation.cc
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-indentation.h"
#include "selftest.h"
#include "diagnostic.h"
+#include "diagnostics/file-cache.h"
/* Round up VIS_COLUMN to nearest tab stop. */
@@ -45,13 +46,13 @@ next_tab_stop (unsigned int vis_column, unsigned int tab_width)
on the line (up to or before EXPLOC). */
static bool
-get_visual_column (file_cache &fc,
+get_visual_column (diagnostics::file_cache &fc,
expanded_location exploc,
unsigned int *out,
unsigned int *first_nws,
unsigned int tab_width)
{
- char_span line = fc.get_source_line (exploc.file, exploc.line);
+ diagnostics::char_span line = fc.get_source_line (exploc.file, exploc.line);
if (!line)
return false;
if ((size_t)exploc.column > line.length ())
@@ -88,14 +89,14 @@ get_visual_column (file_cache &fc,
Otherwise, return false, leaving *FIRST_NWS untouched. */
static bool
-get_first_nws_vis_column (file_cache &fc,
+get_first_nws_vis_column (diagnostics::file_cache &fc,
const char *file, int line_num,
unsigned int *first_nws,
unsigned int tab_width)
{
gcc_assert (first_nws);
- char_span line = fc.get_source_line (file, line_num);
+ diagnostics::char_span line = fc.get_source_line (file, line_num);
if (!line)
return false;
unsigned int vis_column = 0;
@@ -160,7 +161,7 @@ get_first_nws_vis_column (file_cache &fc,
Return true if such an unindent/outdent is detected. */
static bool
-detect_intervening_unindent (file_cache &fc,
+detect_intervening_unindent (diagnostics::file_cache &fc,
const char *file,
int body_line,
int next_stmt_line,
@@ -329,13 +330,13 @@ should_warn_for_misleading_indentation (const token_indent_info &guard_tinfo,
if (guard_loc == body_loc || body_loc == next_stmt_loc)
return false;
- const unsigned int tab_width = global_dc->m_tabstop;
+ const unsigned int tab_width = global_dc->get_column_options ().m_tabstop;
/* They must be in the same file. */
if (next_stmt_exploc.file != body_exploc.file)
return false;
- file_cache &fc = global_dc->get_file_cache ();
+ diagnostics::file_cache &fc = global_dc->get_file_cache ();
/* If NEXT_STMT_LOC and BODY_LOC are on the same line, consider
the location of the guard.
@@ -691,7 +692,7 @@ test_next_tab_stop ()
static void
assert_get_visual_column_succeeds (const location &loc,
- file_cache &fc,
+ diagnostics::file_cache &fc,
const char *file, int line, int column,
const unsigned int tab_width,
unsigned int expected_visual_column,
@@ -735,7 +736,7 @@ assert_get_visual_column_succeeds (const location &loc,
static void
assert_get_visual_column_fails (const location &loc,
- file_cache &fc,
+ diagnostics::file_cache &fc,
const char *file, int line, int column,
const unsigned int tab_width)
{
@@ -783,7 +784,7 @@ test_get_visual_column ()
"\t line 2\n");
line_table_test ltt;
temp_source_file tmp (SELFTEST_LOCATION, ".txt", content);
- file_cache fc;
+ diagnostics::file_cache fc;
const unsigned int tab_width = 8;
const char *file = tmp.get_filename ();
diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc
index fef6ae6..b45d722 100644
--- a/gcc/c-family/c-lex.cc
+++ b/gcc/c-family/c-lex.cc
@@ -1176,7 +1176,7 @@ interpret_integer (const cpp_token *token, unsigned int flags,
&& (flags & CPP_N_WIDTH) != CPP_N_LARGE)
emit_diagnostic
((c_dialect_cxx () ? cxx_dialect == cxx98 : !flag_isoc99)
- ? DK_PEDWARN : DK_WARNING,
+ ? diagnostics::kind::pedwarn : diagnostics::kind::warning,
input_location, OPT_Wlong_long,
(flags & CPP_N_UNSIGNED)
? "integer constant is too large for %<unsigned long%> type"
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index a92c6e3..e183c40 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -52,8 +52,8 @@ c_finish_oacc_wait (location_t loc, tree parms, tree clauses)
vec_alloc (args, nparms + 2);
stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
- if (omp_find_clause (clauses, OMP_CLAUSE_ASYNC))
- t = OMP_CLAUSE_ASYNC_EXPR (clauses);
+ if ((t = omp_find_clause (clauses, OMP_CLAUSE_ASYNC)))
+ t = OMP_CLAUSE_ASYNC_EXPR (t);
else
t = build_int_cst (integer_type_node, GOMP_ASYNC_SYNC);
@@ -71,6 +71,11 @@ c_finish_oacc_wait (location_t loc, tree parms, tree clauses)
stmt = build_call_expr_loc_vec (loc, stmt, args);
+ t = omp_find_clause (clauses, OMP_CLAUSE_IF);
+ if (t)
+ stmt = build3_loc (input_location, COND_EXPR, void_type_node,
+ OMP_CLAUSE_IF_EXPR (t), stmt, NULL_TREE);
+
vec_free (args);
return stmt;
@@ -764,9 +769,7 @@ c_finish_omp_depobj (location_t loc, tree depobj,
kind = OMP_CLAUSE_DEPEND_KIND (clause);
t = OMP_CLAUSE_DECL (clause);
gcc_assert (t);
- if (TREE_CODE (t) == TREE_LIST
- && TREE_PURPOSE (t)
- && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
+ if (OMP_ITERATOR_DECL_P (t))
{
error_at (OMP_CLAUSE_LOCATION (clause),
"%<iterator%> modifier may not be specified on "
@@ -2173,11 +2176,12 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
{
/* First the clauses that are unique to some constructs. */
case OMP_CLAUSE_DEVICE:
- case OMP_CLAUSE_MAP:
- case OMP_CLAUSE_IS_DEVICE_PTR:
- case OMP_CLAUSE_HAS_DEVICE_ADDR:
case OMP_CLAUSE_DEFAULTMAP:
case OMP_CLAUSE_DEPEND:
+ case OMP_CLAUSE_DYN_GROUPPRIVATE:
+ case OMP_CLAUSE_IS_DEVICE_PTR:
+ case OMP_CLAUSE_HAS_DEVICE_ADDR:
+ case OMP_CLAUSE_MAP:
s = C_OMP_CLAUSE_SPLIT_TARGET;
break;
case OMP_CLAUSE_DOACROSS:
@@ -4282,6 +4286,306 @@ c_omp_address_inspector::expand_map_clause (tree c, tree expr,
return error_mark_node;
}
+/* Given a mapper function MAPPER_FN, recursively scan through the map clauses
+ for that mapper, and if any of those should use a (named or unnamed) mapper
+ themselves, add it to MLIST. */
+
+void
+c_omp_find_nested_mappers (omp_mapper_list<tree> *mlist, tree mapper_fn)
+{
+ tree mapper = lang_hooks.decls.omp_extract_mapper_directive (mapper_fn);
+ tree mapper_name = NULL_TREE;
+
+ if (mapper == error_mark_node)
+ return;
+
+ gcc_assert (TREE_CODE (mapper) == OMP_DECLARE_MAPPER);
+
+ for (tree clause = OMP_DECLARE_MAPPER_CLAUSES (mapper);
+ clause;
+ clause = OMP_CLAUSE_CHAIN (clause))
+ {
+ tree expr = OMP_CLAUSE_DECL (clause);
+ enum gomp_map_kind clause_kind = OMP_CLAUSE_MAP_KIND (clause);
+ tree elem_type;
+
+ if (clause_kind == GOMP_MAP_PUSH_MAPPER_NAME)
+ {
+ mapper_name = expr;
+ continue;
+ }
+ else if (clause_kind == GOMP_MAP_POP_MAPPER_NAME)
+ {
+ mapper_name = NULL_TREE;
+ continue;
+ }
+
+ gcc_assert (TREE_CODE (expr) != TREE_LIST);
+ if (TREE_CODE (expr) == OMP_ARRAY_SECTION)
+ {
+ while (TREE_CODE (expr) == OMP_ARRAY_SECTION)
+ expr = TREE_OPERAND (expr, 0);
+
+ elem_type = TREE_TYPE (expr);
+ }
+ else
+ elem_type = TREE_TYPE (expr);
+
+ /* This might be too much... or not enough? */
+ while (TREE_CODE (elem_type) == ARRAY_TYPE
+ || TREE_CODE (elem_type) == POINTER_TYPE
+ || TREE_CODE (elem_type) == REFERENCE_TYPE)
+ elem_type = TREE_TYPE (elem_type);
+
+ elem_type = TYPE_MAIN_VARIANT (elem_type);
+
+ if (RECORD_OR_UNION_TYPE_P (elem_type)
+ && !mlist->contains (mapper_name, elem_type))
+ {
+ tree nested_mapper_fn
+ = lang_hooks.decls.omp_mapper_lookup (mapper_name, elem_type);
+
+ if (nested_mapper_fn)
+ {
+ mlist->add_mapper (mapper_name, elem_type, nested_mapper_fn);
+ c_omp_find_nested_mappers (mlist, nested_mapper_fn);
+ }
+ else if (mapper_name)
+ {
+ error ("mapper %qE not found for type %qT", mapper_name,
+ elem_type);
+ continue;
+ }
+ }
+ }
+}
+
+struct remap_mapper_decl_info
+{
+ tree dummy_var;
+ tree expr;
+};
+
+/* Helper for rewriting DUMMY_VAR into EXPR in a map clause decl. */
+
+static tree
+remap_mapper_decl_1 (tree *tp, int *walk_subtrees, void *data)
+{
+ remap_mapper_decl_info *map_info = (remap_mapper_decl_info *) data;
+
+ if (operand_equal_p (*tp, map_info->dummy_var))
+ {
+ *tp = map_info->expr;
+ *walk_subtrees = 0;
+ }
+
+ return NULL_TREE;
+}
+
+/* Instantiate a mapper MAPPER for expression EXPR, adding new clauses to
+ OUTLIST. OUTER_KIND is the mapping kind to use if not already specified in
+ the mapper declaration. */
+
+static tree *
+omp_instantiate_mapper (tree *outlist, tree mapper, tree expr,
+ enum gomp_map_kind outer_kind)
+{
+ tree clauses = OMP_DECLARE_MAPPER_CLAUSES (mapper);
+ tree dummy_var = OMP_DECLARE_MAPPER_DECL (mapper);
+ tree mapper_name = NULL_TREE;
+
+ remap_mapper_decl_info map_info;
+ map_info.dummy_var = dummy_var;
+ map_info.expr = expr;
+
+ for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ {
+ tree unshared = unshare_expr (c);
+ enum gomp_map_kind clause_kind = OMP_CLAUSE_MAP_KIND (c);
+ tree t = OMP_CLAUSE_DECL (unshared);
+ tree type = NULL_TREE;
+ bool nonunit_array_with_mapper = false;
+
+ if (clause_kind == GOMP_MAP_PUSH_MAPPER_NAME)
+ {
+ mapper_name = t;
+ continue;
+ }
+ else if (clause_kind == GOMP_MAP_POP_MAPPER_NAME)
+ {
+ mapper_name = NULL_TREE;
+ continue;
+ }
+
+ if (TREE_CODE (t) == OMP_ARRAY_SECTION)
+ {
+ location_t loc = OMP_CLAUSE_LOCATION (c);
+ tree t2 = lang_hooks.decls.omp_map_array_section (loc, t);
+
+ if (t2 == t)
+ {
+ nonunit_array_with_mapper = true;
+ /* We'd want use the mapper for the element type if this worked:
+ look that one up. */
+ type = TREE_TYPE (TREE_TYPE (t));
+ }
+ else
+ {
+ t = t2;
+ type = TREE_TYPE (t);
+ }
+ }
+ else
+ type = TREE_TYPE (t);
+
+ gcc_assert (type);
+
+ if (type == error_mark_node)
+ continue;
+
+ walk_tree (&unshared, remap_mapper_decl_1, &map_info, NULL);
+
+ if (OMP_CLAUSE_MAP_KIND (unshared) == GOMP_MAP_UNSET)
+ OMP_CLAUSE_SET_MAP_KIND (unshared, outer_kind);
+
+ type = TYPE_MAIN_VARIANT (type);
+
+ tree mapper_fn = lang_hooks.decls.omp_mapper_lookup (mapper_name, type);
+
+ if (mapper_fn && nonunit_array_with_mapper)
+ {
+ sorry ("user-defined mapper with non-unit length array section");
+ continue;
+ }
+ else if (mapper_fn)
+ {
+ tree nested_mapper
+ = lang_hooks.decls.omp_extract_mapper_directive (mapper_fn);
+ if (nested_mapper != mapper)
+ {
+ if (clause_kind == GOMP_MAP_UNSET)
+ clause_kind = outer_kind;
+
+ outlist = omp_instantiate_mapper (outlist, nested_mapper,
+ t, clause_kind);
+ continue;
+ }
+ }
+ else if (mapper_name)
+ {
+ error ("mapper %qE not found for type %qT", mapper_name, type);
+ continue;
+ }
+
+ *outlist = unshared;
+ outlist = &OMP_CLAUSE_CHAIN (unshared);
+ }
+
+ return outlist;
+}
+
+/* Given a list of CLAUSES, scan each clause and invoke a user-defined mapper
+ appropriate to the type of the data in that clause, if such a mapper is
+ visible in the current parsing context. */
+
+tree
+c_omp_instantiate_mappers (tree clauses)
+{
+ tree c, *pc, mapper_name = NULL_TREE;
+
+ for (pc = &clauses, c = clauses; c; c = *pc)
+ {
+ bool using_mapper = false;
+
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_MAP:
+ {
+ tree t = OMP_CLAUSE_DECL (c);
+ tree type = NULL_TREE;
+ bool nonunit_array_with_mapper = false;
+
+ if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_PUSH_MAPPER_NAME
+ || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POP_MAPPER_NAME)
+ {
+ if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_PUSH_MAPPER_NAME)
+ mapper_name = OMP_CLAUSE_DECL (c);
+ else
+ mapper_name = NULL_TREE;
+ pc = &OMP_CLAUSE_CHAIN (c);
+ continue;
+ }
+
+ if (TREE_CODE (t) == OMP_ARRAY_SECTION)
+ {
+ location_t loc = OMP_CLAUSE_LOCATION (c);
+ tree t2 = lang_hooks.decls.omp_map_array_section (loc, t);
+
+ if (t2 == t)
+ {
+ /* !!! Array sections of size >1 with mappers for elements
+ are hard to support. Do something here. */
+ nonunit_array_with_mapper = true;
+ type = TREE_TYPE (TREE_TYPE (t));
+ }
+ else
+ {
+ t = t2;
+ type = TREE_TYPE (t);
+ }
+ }
+ else
+ type = TREE_TYPE (t);
+
+ if (type == NULL_TREE || type == error_mark_node)
+ {
+ pc = &OMP_CLAUSE_CHAIN (c);
+ continue;
+ }
+
+ enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
+ if (kind == GOMP_MAP_UNSET)
+ kind = GOMP_MAP_TOFROM;
+
+ type = TYPE_MAIN_VARIANT (type);
+
+ tree mapper_fn
+ = lang_hooks.decls.omp_mapper_lookup (mapper_name, type);
+
+ if (mapper_fn && nonunit_array_with_mapper)
+ {
+ sorry ("user-defined mapper with non-unit length "
+ "array section");
+ using_mapper = true;
+ }
+ else if (mapper_fn)
+ {
+ tree mapper
+ = lang_hooks.decls.omp_extract_mapper_directive (mapper_fn);
+ pc = omp_instantiate_mapper (pc, mapper, t, kind);
+ using_mapper = true;
+ }
+ else if (mapper_name)
+ {
+ error ("mapper %qE not found for type %qT", mapper_name, type);
+ using_mapper = true;
+ }
+ }
+ break;
+
+ default:
+ ;
+ }
+
+ if (using_mapper)
+ *pc = OMP_CLAUSE_CHAIN (c);
+ else
+ pc = &OMP_CLAUSE_CHAIN (c);
+ }
+
+ return clauses;
+}
+
const struct c_omp_directive c_omp_directives[] = {
/* Keep this alphabetically sorted by the first word. Non-null second/third
if any should precede null ones. */
@@ -4299,8 +4603,11 @@ const struct c_omp_directive c_omp_directives[] = {
C_OMP_DIR_INFORMATIONAL, false },
{ "begin", "declare", "target", PRAGMA_OMP_BEGIN,
C_OMP_DIR_DECLARATIVE, false },
- /* { "begin", "declare", "variant", PRAGMA_OMP_BEGIN,
- C_OMP_DIR_DECLARATIVE, false }, */
+ { "begin", "declare", "variant", PRAGMA_OMP_BEGIN,
+ C_OMP_DIR_DECLARATIVE, false },
+ /* 'begin metadirective' is not yet implemented; however,
+ it is only applicable if an end-directive exists, but
+ metadirectives are of limited use for declarative directives. */
/* { "begin", "metadirective", nullptr, PRAGMA_OMP_BEGIN,
C_OMP_DIR_META, false }, */
{ "cancel", nullptr, nullptr, PRAGMA_OMP_CANCEL,
@@ -4309,8 +4616,10 @@ const struct c_omp_directive c_omp_directives[] = {
C_OMP_DIR_STANDALONE, false },
{ "critical", nullptr, nullptr, PRAGMA_OMP_CRITICAL,
C_OMP_DIR_CONSTRUCT, false },
- /* { "declare", "mapper", nullptr, PRAGMA_OMP_DECLARE,
- C_OMP_DIR_DECLARATIVE, false }, */
+ /* { "declare", "induction", nullptr, PRAGMA_OMP_DECLARE,
+ C_OMP_DIR_DECLARATIVE, true }, */
+ { "declare", "mapper", nullptr, PRAGMA_OMP_DECLARE,
+ C_OMP_DIR_DECLARATIVE, false },
{ "declare", "reduction", nullptr, PRAGMA_OMP_DECLARE,
C_OMP_DIR_DECLARATIVE, true },
{ "declare", "simd", nullptr, PRAGMA_OMP_DECLARE,
@@ -4329,19 +4638,25 @@ const struct c_omp_directive c_omp_directives[] = {
C_OMP_DIR_INFORMATIONAL, false },
{ "end", "declare", "target", PRAGMA_OMP_END,
C_OMP_DIR_DECLARATIVE, false },
- /* { "end", "declare", "variant", PRAGMA_OMP_END,
- C_OMP_DIR_DECLARATIVE, false }, */
+ { "end", "declare", "variant", PRAGMA_OMP_END,
+ C_OMP_DIR_DECLARATIVE, false },
/* { "end", "metadirective", nullptr, PRAGMA_OMP_END,
C_OMP_DIR_META, false }, */
/* error with at(execution) is C_OMP_DIR_STANDALONE. */
{ "error", nullptr, nullptr, PRAGMA_OMP_ERROR,
C_OMP_DIR_UTILITY, false },
+ /* { "flatten", nullptr, nullptr, PRAGMA_OMP_FLATTEN,
+ C_OMP_DIR_CONSTRUCT, true }, */
{ "flush", nullptr, nullptr, PRAGMA_OMP_FLUSH,
C_OMP_DIR_STANDALONE, false },
{ "for", nullptr, nullptr, PRAGMA_OMP_FOR,
C_OMP_DIR_CONSTRUCT, true },
+ /* { "fuse", nullptr, nullptr, PRAGMA_OMP_FUSE,
+ C_OMP_DIR_CONSTRUCT, true }, */
/* { "groupprivate", nullptr, nullptr, PRAGMA_OMP_GROUPPRIVATE,
C_OMP_DIR_DECLARATIVE, false }, */
+ /* { "interchange", nullptr, nullptr, PRAGMA_OMP_INTERCHANGE,
+ C_OMP_DIR_CONSTRUCT, true }, */
{ "interop", nullptr, nullptr, PRAGMA_OMP_INTEROP,
C_OMP_DIR_STANDALONE, false },
{ "loop", nullptr, nullptr, PRAGMA_OMP_LOOP,
@@ -4373,6 +4688,10 @@ const struct c_omp_directive c_omp_directives[] = {
C_OMP_DIR_CONSTRUCT, true },
{ "single", nullptr, nullptr, PRAGMA_OMP_SINGLE,
C_OMP_DIR_CONSTRUCT, false },
+ /* { "split", nullptr, nullptr, PRAGMA_OMP_SPLIT,
+ C_OMP_DIR_CONSTRUCT, true }, */
+ /* { "stripe", nullptr, nullptr, PRAGMA_OMP_STRIPE,
+ C_OMP_DIR_CONSTRUCT, true }, */
{ "target", "data", nullptr, PRAGMA_OMP_TARGET,
C_OMP_DIR_CONSTRUCT, false },
{ "target", "enter", "data", PRAGMA_OMP_TARGET,
@@ -4385,6 +4704,10 @@ const struct c_omp_directive c_omp_directives[] = {
C_OMP_DIR_CONSTRUCT, true },
{ "task", nullptr, nullptr, PRAGMA_OMP_TASK,
C_OMP_DIR_CONSTRUCT, false },
+ /* { "task", "iteration", nullptr, PRAGMA_OMP_TASK_ITERATION,
+ C_OMP_DIR_STANDALONE, false }, */
+ /* { "taskgraph", nullptr, nullptr, PRAGMA_OMP_TASKGRAPH,
+ C_OMP_DIR_CONSTRUCT, false }, */
{ "taskgroup", nullptr, nullptr, PRAGMA_OMP_TASKGROUP,
C_OMP_DIR_CONSTRUCT, false },
{ "taskloop", nullptr, nullptr, PRAGMA_OMP_TASKLOOP,
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index 4016382..8da5175 100644
--- a/gcc/c-family/c-opts.cc
+++ b/gcc/c-family/c-opts.cc
@@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define INCLUDE_VECTOR
#include "config.h"
#include "system.h"
#include "coretypes.h"
@@ -32,7 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "toplev.h"
#include "langhooks.h"
-#include "diagnostic-macro-unwinding.h" /* for virt_loc_aware_diagnostic_finalizer */
+#include "diagnostics/macro-unwinding.h" /* for virt_loc_aware_diagnostic_finalizer */
#include "intl.h"
#include "cppdefault.h"
#include "incpath.h"
@@ -43,7 +44,7 @@ along with GCC; see the file COPYING3. If not see
#include "dumpfile.h"
#include "file-prefix-map.h" /* add_*_prefix_map() */
#include "context.h"
-#include "diagnostic-format-text.h"
+#include "diagnostics/text-sink.h"
#ifndef DOLLARS_IN_IDENTIFIERS
# define DOLLARS_IN_IDENTIFIERS true
@@ -169,9 +170,9 @@ c_common_option_lang_mask (void)
/* Diagnostic finalizer for C/C++/Objective-C/Objective-C++. */
static void
-c_diagnostic_text_finalizer (diagnostic_text_output_format &text_output,
- const diagnostic_info *diagnostic,
- diagnostic_t)
+c_diagnostic_text_finalizer (diagnostics::text_sink &text_output,
+ const diagnostics::diagnostic_info *diagnostic,
+ enum diagnostics::kind)
{
pretty_printer *const pp = text_output.get_printer ();
char *saved_prefix = pp_take_prefix (pp);
@@ -179,20 +180,20 @@ c_diagnostic_text_finalizer (diagnostic_text_output_format &text_output,
pp_newline (pp);
diagnostic_show_locus (&text_output.get_context (),
text_output.get_source_printing_options (),
- diagnostic->richloc, diagnostic->kind, pp);
+ diagnostic->m_richloc, diagnostic->m_kind, pp);
/* By default print macro expansion contexts in the diagnostic
finalizer -- for tokens resulting from macro expansion. */
- virt_loc_aware_diagnostic_finalizer (text_output, diagnostic);
+ diagnostics::virt_loc_aware_text_finalizer (text_output, diagnostic);
pp_set_prefix (pp, saved_prefix);
pp_flush (pp);
}
/* Common default settings for diagnostics. */
void
-c_common_diagnostics_set_defaults (diagnostic_context *context)
+c_common_diagnostics_set_defaults (diagnostics::context *context)
{
- diagnostic_text_finalizer (context) = c_diagnostic_text_finalizer;
- context->m_opt_permissive = OPT_fpermissive;
+ diagnostics::text_finalizer (context) = c_diagnostic_text_finalizer;
+ context->set_permissive_option (OPT_fpermissive);
}
/* Input charset configuration for diagnostics. */
@@ -229,7 +230,6 @@ c_common_init_options_struct (struct gcc_options *opts)
/* By default, C99-like requirements for complex multiply and divide. */
opts->x_flag_complex_method = 2;
- opts->x_flag_default_complex_method = opts->x_flag_complex_method;
}
/* Common initialization before calling option handlers. */
@@ -274,11 +274,11 @@ c_common_init_options (unsigned int decoded_options_count,
}
}
- /* Set C++ standard to C++17 if not specified on the command line. */
+ /* Set C++ standard to C++20 if not specified on the command line. */
if (c_dialect_cxx ())
- set_std_cxx17 (/*ISO*/false);
+ set_std_cxx20 (/*ISO*/false);
- global_dc->m_source_printing.colorize_source_p = true;
+ global_dc->get_source_printing_options ().colorize_source_p = true;
}
/* Handle switch SCODE with argument ARG. VALUE is true, unless no-
@@ -864,8 +864,12 @@ c_common_post_options (const char **pfilename)
sanitize_cpp_opts ();
- register_include_chains (parse_in, sysroot, iprefix, imultilib,
- std_inc, std_cxx_inc && c_dialect_cxx (), verbose);
+ /* Don't register include chains if under -fpreprocessed since we might not
+ have correct sysroot this mode, and this may cause file permssion
+ issue. */
+ if (!cpp_opts->preprocessed)
+ register_include_chains (parse_in, sysroot, iprefix, imultilib,
+ std_inc, std_cxx_inc && c_dialect_cxx (), verbose);
#ifdef C_COMMON_OVERRIDE_OPTIONS
/* Some machines may reject certain combinations of C
@@ -913,6 +917,16 @@ c_common_post_options (const char **pfilename)
else
flag_permitted_flt_eval_methods = PERMITTED_FLT_EVAL_METHODS_C11;
+ if (cxx_dialect >= cxx26)
+ SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+ flag_auto_var_init, AUTO_INIT_CXX26);
+
+ /* The -Wtrivial-auto-var-init warning is useless for C++, where we always
+ add .DEFERRED_INIT calls when some (vacuous) initializers are bypassed
+ through jumps from switch condition to case/default label. */
+ if (c_dialect_cxx ())
+ warn_trivial_auto_var_init = 0;
+
/* C23 Annex F does not permit certain built-in functions to raise
"inexact". */
if (flag_isoc23)
@@ -959,6 +973,15 @@ c_common_post_options (const char **pfilename)
if (warn_enum_compare == -1)
warn_enum_compare = c_dialect_cxx () ? 1 : 0;
+ /* For C++26 default to -Wkeyword-macro if -Wpedantic. */
+ if (cxx_dialect >= cxx26 && pedantic)
+ {
+ SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+ warn_keyword_macro, 1);
+ if (warn_keyword_macro)
+ cpp_opts->cpp_warn_keyword_macro = warn_keyword_macro;
+ }
+
/* -Wpacked-bitfield-compat is on by default for the C languages. The
warning is issued in stor-layout.cc which is not part of the front-end so
we need to selectively turn it on here. */
@@ -1085,12 +1108,21 @@ c_common_post_options (const char **pfilename)
/* Change flag_abi_version to be the actual current ABI level, for the
benefit of c_cpp_builtins, and to make comparison simpler. */
const int latest_abi_version = 21;
+ /* Possibly different for non-default ABI fixes within a release. */
+ const int default_abi_version = latest_abi_version;
/* Generate compatibility aliases for ABI v18 (GCC 13) by default. */
const int abi_compat_default = 18;
+ if (flag_abi_version > latest_abi_version)
+ warning (0, "%<-fabi-version=%d%> is not supported, using =%d",
+ flag_abi_version, latest_abi_version);
+
+ SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+ flag_abi_version, default_abi_version);
+
#define clamp(X) if (X == 0 || X > latest_abi_version) X = latest_abi_version
clamp (flag_abi_version);
- clamp (warn_abi_version);
+ /* Don't clamp warn_abi_version, let it be 0 or out of bounds. */
clamp (flag_abi_compat_version);
#undef clamp
@@ -1101,24 +1133,17 @@ c_common_post_options (const char **pfilename)
flag_abi_compat_version = warn_abi_version;
else if (warn_abi_version == -1 && flag_abi_compat_version == -1)
{
- warn_abi_version = latest_abi_version;
- if (flag_abi_version == latest_abi_version)
- {
- auto_diagnostic_group d;
- if (warning (OPT_Wabi, "%<-Wabi%> won%'t warn about anything"))
- {
- inform (input_location, "%<-Wabi%> warns about differences "
- "from the most up-to-date ABI, which is also used "
- "by default");
- inform (input_location, "use e.g. %<-Wabi=11%> to warn about "
- "changes from GCC 7");
- }
- flag_abi_compat_version = abi_compat_default;
- }
+ warn_abi_version = 0;
+ if (flag_abi_version == default_abi_version)
+ flag_abi_compat_version = abi_compat_default;
else
flag_abi_compat_version = latest_abi_version;
}
+ /* Allow warnings vs ABI versions beyond what we currently support. */
+ if (warn_abi_version == 0)
+ warn_abi_version = 1000;
+
/* By default, enable the new inheriting constructor semantics along with ABI
11. New and old should coexist fine, but it is a change in what
artificial symbols are generated. */
@@ -1163,6 +1188,9 @@ c_common_post_options (const char **pfilename)
warn_cxx20_compat = 0;
cpp_opts->cpp_warn_cxx20_compat = 0;
}
+ if (cxx_dialect >= cxx26)
+ /* Don't warn about C++26 compatibility changes in C++26 or later. */
+ warn_cxx26_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. */
@@ -1186,7 +1214,7 @@ c_common_post_options (const char **pfilename)
flag_char8_t = (cxx_dialect >= cxx20) || flag_isoc23;
cpp_opts->unsigned_utf8char = flag_char8_t ? 1 : cpp_opts->unsigned_char;
- cpp_opts->cpp_tabstop = global_dc->m_tabstop;
+ cpp_opts->cpp_tabstop = global_dc->get_column_options ().m_tabstop;
if (flag_extern_tls_init)
{
@@ -1213,10 +1241,25 @@ c_common_post_options (const char **pfilename)
if (cxx_dialect >= cxx20)
flag_concepts = 1;
+ /* Coroutines are also a C++20 feature. */
+ SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+ flag_coroutines, cxx_dialect >= cxx20);
+
/* Enable lifetime extension of range based for temporaries for C++23. */
SET_OPTION_IF_UNSET (&global_options, &global_options_set,
flag_range_for_ext_temps, cxx_dialect >= cxx23);
+ /* EnabledBy unfortunately can't specify value to use if set and
+ LangEnabledBy can't specify multiple options with &&. For -Wunused
+ or -Wunused -Wextra we want these to default to 3 unless user specified
+ some other level explicitly. */
+ if (warn_unused_but_set_parameter == 1)
+ SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+ warn_unused_but_set_parameter, 3);
+ if (warn_unused_but_set_variable == 1)
+ SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+ warn_unused_but_set_variable, 3);
+
/* -fimmediate-escalation has no effect when immediate functions are not
supported. */
if (flag_immediate_escalation && cxx_dialect < cxx20)
@@ -1661,6 +1704,7 @@ c_finish_options (void)
bool cxx_assert_seen_p = false;
/* All command line defines must have the same location. */
+ line_table->cmdline_location = line_table->highest_line;
cpp_force_token_locations (parse_in, line_table->highest_line);
for (size_t i = 0; i < deferred_count; i++)
{
@@ -2007,8 +2051,6 @@ set_std_cxx20 (int iso)
flag_isoc94 = 1;
flag_isoc99 = 1;
flag_isoc11 = 1;
- /* C++20 includes coroutines. */
- flag_coroutines = true;
cxx_dialect = cxx20;
lang_hooks.name = "GNU C++20";
}
@@ -2025,8 +2067,6 @@ set_std_cxx23 (int iso)
flag_isoc94 = 1;
flag_isoc99 = 1;
flag_isoc11 = 1;
- /* C++23 includes coroutines. */
- flag_coroutines = true;
cxx_dialect = cxx23;
lang_hooks.name = "GNU C++23";
}
@@ -2043,8 +2083,6 @@ set_std_cxx26 (int iso)
flag_isoc94 = 1;
flag_isoc99 = 1;
flag_isoc11 = 1;
- /* C++26 includes coroutines. */
- flag_coroutines = true;
cxx_dialect = cxx26;
lang_hooks.name = "GNU C++26";
}
diff --git a/gcc/c-family/c-pch.cc b/gcc/c-family/c-pch.cc
index b8f075e..8f0fea8 100644
--- a/gcc/c-family/c-pch.cc
+++ b/gcc/c-family/c-pch.cc
@@ -347,18 +347,18 @@ c_common_read_pch (cpp_reader *pfile, const char *name,
rebuild_location_adhoc_htab (line_table);
line_table->trace_includes = saved_trace_includes;
- /* Set the current location to the line containing the #include (or the
- #pragma GCC pch_preprocess) for the purpose of assigning locations to any
- macros that are about to be restored. */
- linemap_add (line_table, LC_ENTER, 0, saved_loc.file,
- saved_loc.line > 1 ? saved_loc.line - 1 : saved_loc.line);
+ /* Set the line_map current location to the start of the file, so that things
+ remain in order after cpp_read_state() re-adds any macros that were defined
+ prior to calling gt_pch_restore(). */
+ linemap_add (line_table, LC_ENTER, saved_loc.sysp, saved_loc.file, 0);
timevar_push (TV_PCH_CPP_RESTORE);
cpp_result = cpp_read_state (pfile, name, f, smd);
/* Set the current location to the line following the #include, where we
were prior to processing the PCH. */
- linemap_line_start (line_table, saved_loc.line, 0);
+ linemap_add (line_table, LC_RENAME, saved_loc.sysp, saved_loc.file,
+ saved_loc.line);
timevar_pop (TV_PCH_CPP_RESTORE);
diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc
index 8b5cdcc..8a1218b 100644
--- a/gcc/c-family/c-pragma.cc
+++ b/gcc/c-family/c-pragma.cc
@@ -781,7 +781,7 @@ public:
PK_IGNORED_ATTRIBUTES,
PK_DIAGNOSTIC,
} pd_kind;
- diagnostic_t diagnostic_kind;
+ enum diagnostics::kind diagnostic_kind;
const char *kind_str;
const char *option_str;
bool own_option_str;
@@ -792,7 +792,7 @@ public:
valid = false;
loc_kind = loc_option = UNKNOWN_LOCATION;
pd_kind = PK_INVALID;
- diagnostic_kind = DK_UNSPECIFIED;
+ diagnostic_kind = diagnostics::kind::unspecified;
kind_str = option_str = nullptr;
own_option_str = false;
}
@@ -808,7 +808,7 @@ public:
kind_str = kind_string;
pd_kind = PK_INVALID;
- diagnostic_kind = DK_UNSPECIFIED;
+ diagnostic_kind = diagnostics::kind::unspecified;
if (strcmp (kind_str, "push") == 0)
pd_kind = PK_PUSH;
else if (strcmp (kind_str, "pop") == 0)
@@ -818,17 +818,17 @@ public:
else if (strcmp (kind_str, "error") == 0)
{
pd_kind = PK_DIAGNOSTIC;
- diagnostic_kind = DK_ERROR;
+ diagnostic_kind = diagnostics::kind::error;
}
else if (strcmp (kind_str, "warning") == 0)
{
pd_kind = PK_DIAGNOSTIC;
- diagnostic_kind = DK_WARNING;
+ diagnostic_kind = diagnostics::kind::warning;
}
else if (strcmp (kind_str, "ignored") == 0)
{
pd_kind = PK_DIAGNOSTIC;
- diagnostic_kind = DK_IGNORED;
+ diagnostic_kind = diagnostics::kind::ignored;
}
}
@@ -1016,7 +1016,8 @@ handle_pragma_diagnostic_impl ()
what we used to do here before and changing it breaks e.g.
PR69543 and PR69558. */
control_warning_option (option_index, (int) data.diagnostic_kind,
- arg, data.diagnostic_kind != DK_IGNORED,
+ arg,
+ data.diagnostic_kind != diagnostics::kind::ignored,
input_location, lang_mask, &handlers,
&global_options, &global_options_set,
global_dc);
@@ -1847,7 +1848,9 @@ init_pragma (void)
c_register_pragma_with_early_handler ("GCC", "target",
handle_pragma_target,
handle_pragma_target);
- c_register_pragma ("GCC", "optimize", handle_pragma_optimize);
+ c_register_pragma_with_early_handler ("GCC", "optimize",
+ handle_pragma_optimize,
+ handle_pragma_optimize);
c_register_pragma_with_early_handler ("GCC", "push_options",
handle_pragma_push_options,
handle_pragma_push_options);
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index 13df9ea..a61a2c7 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -119,6 +119,7 @@ enum pragma_omp_clause {
PRAGMA_OMP_CLAUSE_DEVICE_TYPE,
PRAGMA_OMP_CLAUSE_DIST_SCHEDULE,
PRAGMA_OMP_CLAUSE_DOACROSS,
+ PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE,
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 fad6b5e..5adb13b 100644
--- a/gcc/c-family/c-pretty-print.cc
+++ b/gcc/c-family/c-pretty-print.cc
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "basic-block.h"
#include "gimple.h"
+#include "tm.h"
/* The pretty-printer code is primarily designed to closely follow
(GNU) C and C++ grammars. That is to be contrasted with spaghetti
@@ -45,12 +46,6 @@ along with GCC; see the file COPYING3. If not see
takes expression or declaration contexts into account. */
-#define pp_c_maybe_whitespace(PP) \
- do { \
- if ((PP)->get_padding () == pp_before) \
- pp_c_whitespace (PP); \
- } while (0)
-
/* literal */
static void pp_c_char (c_pretty_printer *, int);
@@ -3054,6 +3049,76 @@ pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
pp_c_identifier (pp, name);
}
+/* Prints "[version: VERSION]" for a versioned function decl.
+ This will only print for targets with target_version semantics. */
+void
+pp_c_function_target_version (c_pretty_printer *pp, tree t)
+{
+ if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
+ return;
+
+ string_slice version = get_target_version (t);
+ if (!version.is_valid ())
+ return;
+
+ pp_c_whitespace (pp);
+
+ pp_c_left_bracket (pp);
+ pp_c_left_bracket (pp);
+ pp_string (pp, "target_version");
+ pp_c_left_paren (pp);
+ pp_doublequote (pp);
+ pp_string_n (pp, version.begin (), version.size ());
+ pp_doublequote (pp);
+ pp_c_right_paren (pp);
+ pp_c_right_bracket (pp);
+ pp_c_right_bracket (pp);
+
+ pp->set_padding (pp_before);
+}
+
+/* Prints "[clones: VERSION, +]" for a versioned function decl.
+ This only works for targets with target_version semantics. */
+void
+pp_c_function_target_clones (c_pretty_printer *pp, tree t)
+{
+ /* Only print for target_version semantics.
+ This is because for target FMV semantics a target_clone always defines
+ the entire FMV set. target_version semantics can mix target_clone and
+ target_version decls in the definition of a FMV set and so the
+ target_clone becomes a part of the identity of the declaration. */
+ if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
+ return;
+
+ auto_vec<string_slice> versions = get_clone_versions (t, NULL, false);
+ if (versions.is_empty ())
+ return;
+
+ pp_c_whitespace (pp);
+
+ string_slice final_version = versions.pop ();
+ pp_c_left_bracket (pp);
+ pp_c_left_bracket (pp);
+ pp_string (pp, "target_clones");
+ pp_c_left_paren (pp);
+ for (string_slice version : versions)
+ {
+ pp_doublequote (pp);
+ pp_string_n (pp, version.begin (), version.size ());
+ pp_doublequote (pp);
+ pp_string (pp, ",");
+ pp_c_whitespace (pp);
+ }
+ pp_doublequote (pp);
+ pp_string_n (pp, final_version.begin (), final_version.size ());
+ pp_doublequote (pp);
+ pp_c_right_paren (pp);
+ pp_c_right_bracket (pp);
+ pp_c_right_bracket (pp);
+
+ pp->set_padding (pp_before);
+}
+
#if CHECKING_P
namespace selftest {
diff --git a/gcc/c-family/c-pretty-print.h b/gcc/c-family/c-pretty-print.h
index c8fb678..5e00b95 100644
--- a/gcc/c-family/c-pretty-print.h
+++ b/gcc/c-family/c-pretty-print.h
@@ -102,6 +102,12 @@ public:
#define pp_ptr_operator(PP, D) (PP)->ptr_operator (PP, D)
#define pp_parameter_list(PP, T) (PP)->parameter_list (PP, T)
+#define pp_c_maybe_whitespace(PP) \
+ do { \
+ if ((PP)->get_padding () == pp_before) \
+ pp_c_whitespace (PP); \
+ } while (0)
+
void pp_c_whitespace (c_pretty_printer *);
void pp_c_left_paren (c_pretty_printer *);
void pp_c_right_paren (c_pretty_printer *);
@@ -138,6 +144,8 @@ void pp_c_ws_string (c_pretty_printer *, const char *);
void pp_c_identifier (c_pretty_printer *, const char *);
void pp_c_string_literal (c_pretty_printer *, tree);
void pp_c_integer_constant (c_pretty_printer *, tree);
+void pp_c_function_target_version (c_pretty_printer *, tree);
+void pp_c_function_target_clones (c_pretty_printer *, tree);
void print_c_tree (FILE *file, tree t, dump_flags_t);
diff --git a/gcc/c-family/c-ubsan.cc b/gcc/c-family/c-ubsan.cc
index 78b7868..29534d7 100644
--- a/gcc/c-family/c-ubsan.cc
+++ b/gcc/c-family/c-ubsan.cc
@@ -397,8 +397,7 @@ get_bound_from_access_with_size (tree call)
return NULL_TREE;
tree ref_to_size = CALL_EXPR_ARG (call, 1);
- unsigned int class_of_size = TREE_INT_CST_LOW (CALL_EXPR_ARG (call, 2));
- tree type = TREE_TYPE (CALL_EXPR_ARG (call, 3));
+ tree type = TREE_TYPE (TREE_TYPE (CALL_EXPR_ARG (call, 2)));
tree size = fold_build2 (MEM_REF, type, unshare_expr (ref_to_size),
build_int_cst (ptr_type_node, 0));
/* If size is negative value, treat it as zero. */
@@ -410,12 +409,7 @@ get_bound_from_access_with_size (tree call)
build_zero_cst (type), size);
}
- /* Only when class_of_size is 1, i.e, the number of the elements of
- the object type, return the size. */
- if (class_of_size != 1)
- return NULL_TREE;
- else
- size = fold_convert (sizetype, size);
+ size = fold_convert (sizetype, size);
return size;
}
@@ -460,7 +454,7 @@ ubsan_instrument_bounds (location_t loc, tree array, tree *index,
bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound,
build_int_cst (TREE_TYPE (bound),
- 1 + ignore_off_by_one));
+ 1 + ignore_off_by_one));
/* Detect flexible array members and suchlike, unless
-fsanitize=bounds-strict. */
@@ -547,45 +541,332 @@ ubsan_instrument_bounds (location_t loc, tree array, tree *index,
return NULL_TREE;
*index = save_expr (*index);
+ /* If TYPE is a VLA, use 1 instead of 0 as the first argument and
+ use just the addend to TYPE_MAX_VALUE (domain) as the third argument
+ temporarily, so that gimplification can use TYPE_MAX_VALUE (domain)
+ after gimplify_type_sizes. See PR120052. */
+ bool is_vla = (TYPE_MAX_VALUE (domain)
+ && TREE_CODE (TYPE_MAX_VALUE (domain)) != INTEGER_CST);
+ if (is_vla)
+ bound = build_int_cst (TREE_TYPE (bound), 1 + ignore_off_by_one);
+ /* Create a "(T *) 0" (or 1) tree node to describe the array type. */
+ tree zero_with_type = build_int_cst (build_pointer_type (type), is_vla);
+ return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
+ void_type_node, 3, zero_with_type,
+ *index, bound);
+}
+
+
+/* Instrument array bounds for the pointer array address which is
+ a call to .ACCESS_WITH_SIZE. We create special
+ builtin, that gets expanded in the sanopt pass, and make an array
+ dimention of it. POINTER_ADDR is the pointer array's base address.
+ *INDEX is an index to the array.
+ IGNORE_OFF_BY_ONE is true if the POINTER_ADDR is not inside an
+ INDIRECT_REF.
+ Return NULL_TREE if no instrumentation is emitted. */
+
+tree
+ubsan_instrument_bounds_pointer_address (location_t loc, tree pointer_addr,
+ tree *index,
+ bool ignore_off_by_one)
+{
+ tree call = pointer_addr;
+ if (!is_access_with_size_p (call))
+ return NULL_TREE;
+ tree bound = get_bound_from_access_with_size (call);
+
+ if (ignore_off_by_one)
+ bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound,
+ build_int_cst (TREE_TYPE (bound),
+ 1));
+
+ /* Don't emit instrumentation in the most common cases. */
+ tree idx = NULL_TREE;
+ if (TREE_CODE (*index) == INTEGER_CST)
+ idx = *index;
+ else if (TREE_CODE (*index) == BIT_AND_EXPR
+ && TREE_CODE (TREE_OPERAND (*index, 1)) == INTEGER_CST)
+ idx = TREE_OPERAND (*index, 1);
+ if (idx
+ && TREE_CODE (bound) == INTEGER_CST
+ && tree_int_cst_sgn (idx) >= 0
+ && tree_int_cst_lt (idx, bound))
+ return NULL_TREE;
+
+ *index = save_expr (*index);
+
+ /* Create an array_type for the corresponding pointer array. */
+ tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
+ /* The array's element type can be get from the return type of the call to
+ .ACCESS_WITH_SIZE. */
+ tree element_type = TREE_TYPE (TREE_TYPE (call));
+ tree array_type = build_array_type (element_type, itype);
/* Create a "(T *) 0" tree node to describe the array type. */
- tree zero_with_type = build_int_cst (build_pointer_type (type), 0);
+ tree zero_with_type = build_int_cst (build_pointer_type (array_type), 0);
return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
void_type_node, 3, zero_with_type,
*index, bound);
}
-/* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS. */
+/* This structure is to combine a factor with its parent and its position
+ * in its parent tree. */
+struct factor_t
+{
+ tree factor;
+ tree parent; /* the parent tree of this factor. */
+ int pos; /* the position of this factor in its parent tree. */
+};
+
+/* for a multiply expression like:
+ ((long unsigned int) m * (long unsigned int) SAVE_EXPR <n>) * 4
+
+ locate all the factors, the parents of the factor and the position of
+ the factor in its parent, and put them to VEC_FACTORS. */
+
+static void
+get_factors_from_mul_expr (tree mult_expr, tree parent,
+ int pos, auto_vec<factor_t> *vec_factors)
+{
+ struct factor_t mult_factor = {0, 0, -1};
+ mult_factor.factor = mult_expr;
+ mult_factor.parent = parent;
+ mult_factor.pos = pos;
+
+ while (CONVERT_EXPR_CODE_P (TREE_CODE (mult_expr)))
+ {
+ mult_factor.parent = mult_expr;
+ mult_factor.pos = 0;
+ mult_expr = TREE_OPERAND (mult_expr, 0);
+ mult_factor.factor = mult_expr;
+ }
+ if (TREE_CODE (mult_expr) != MULT_EXPR)
+ vec_factors->safe_push (mult_factor);
+ else
+ {
+ get_factors_from_mul_expr (TREE_OPERAND (mult_expr, 0), mult_expr,
+ 0, vec_factors);
+ get_factors_from_mul_expr (TREE_OPERAND (mult_expr, 1), mult_expr,
+ 1, vec_factors);
+ }
+}
+
+/* Given an OFFSET expression, and the ELEMENT_SIZE,
+ get the index expression from OFFSET and return it.
+ For example:
+ OFFSET:
+ ((long unsigned int) m * (long unsigned int) SAVE_EXPR <n>) * 4
+ ELEMENT_SIZE:
+ (sizetype) SAVE_EXPR <n> * 4
+ get the index as (long unsigned int) m, and return it.
+ The INDEX_P holds the pointer to the parent tree of the index,
+ INDEX_N holds the position of the index in its parent. */
+
+static tree
+get_index_from_offset (tree offset, tree *index_p,
+ int *index_n, tree element_size)
+{
+ if (TREE_CODE (offset) != MULT_EXPR)
+ return NULL_TREE;
+
+ auto_vec<factor_t> e_factors, o_factors;
+ get_factors_from_mul_expr (element_size, NULL, -1, &e_factors);
+ get_factors_from_mul_expr (offset, *index_p, *index_n, &o_factors);
+
+ if (e_factors.is_empty () || o_factors.is_empty ())
+ return NULL_TREE;
+
+ bool all_found = true;
+ for (unsigned i = 0; i < e_factors.length (); i++)
+ {
+ factor_t e_size_factor = e_factors[i];
+ bool found = false;
+ for (unsigned j = 0; j < o_factors.length ();)
+ {
+ factor_t o_exp_factor = o_factors[j];
+ if (operand_equal_p (e_size_factor.factor, o_exp_factor.factor))
+ {
+ o_factors.unordered_remove (j);
+ found = true;
+ break;
+ }
+ else
+ j++;
+ }
+ if (!found)
+ all_found = false;
+ }
+
+ if (!all_found)
+ return NULL_TREE;
+
+ if (o_factors.length () != 1)
+ return NULL_TREE;
+
+ *index_p = o_factors[0].parent;
+ *index_n = o_factors[0].pos;
+ return o_factors[0].factor;
+}
+
+/* For an pointer + offset computation expression, such as,
+ .ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
+ + (sizetype) ((long unsigned int) index * 4
+ Return the index of this pointer array reference,
+ set the parent tree of INDEX to *INDEX_P.
+ set the operand position of the INDEX in the parent tree to *INDEX_N.
+ If failed, return NULL_TREE. */
+
+static tree
+get_index_from_pointer_addr_expr (tree pointer, tree *index_p, int *index_n)
+{
+ *index_p = NULL_TREE;
+ *index_n = -1;
+ tree call = TREE_OPERAND (pointer, 0);
+ if (!is_access_with_size_p (call))
+ return NULL_TREE;
+
+ /* Get the pointee type of the call to .ACCESS_WITH_SIZE.
+ This should be the element type of the pointer array. */
+ tree pointee_type = TREE_TYPE (TREE_TYPE (call));
+ tree pointee_size = TYPE_SIZE_UNIT (pointee_type);
+
+ tree index_exp = TREE_OPERAND (pointer, 1);
+ *index_p = pointer;
+ *index_n = 1;
+
+ if (!(TREE_CODE (index_exp) != MULT_EXPR
+ && tree_int_cst_equal (pointee_size, integer_one_node)))
+ {
+ while (CONVERT_EXPR_CODE_P (TREE_CODE (index_exp)))
+ {
+ *index_p = index_exp;
+ *index_n = 0;
+ index_exp = TREE_OPERAND (index_exp, 0);
+ }
+ index_exp = get_index_from_offset (index_exp, index_p,
+ index_n, pointee_size);
+
+ if (!index_exp)
+ return NULL_TREE;
+ }
+
+ while (CONVERT_EXPR_CODE_P (TREE_CODE (index_exp)))
+ {
+ *index_p = index_exp;
+ *index_n = 0;
+ index_exp = TREE_OPERAND (index_exp, 0);
+ }
+
+ return index_exp;
+}
+
+/* Return TRUE when the EXPR is a pointer array address that could be
+ instrumented.
+ We only instrument an address computation similar as the following:
+ .ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
+ + (sizetype) ((long unsigned int) index * 4)
+ if the EXPR is instrumentable, return TRUE and
+ set the index to *INDEX.
+ set the .ACCESS_WITH_SIZE to *BASE.
+ set the parent tree of INDEX to *INDEX_P.
+ set the operand position of the INDEX in the parent tree to INDEX_N. */
+
+static bool
+is_instrumentable_pointer_array_address (tree expr, tree *base,
+ tree *index, tree *index_p,
+ int *index_n)
+{
+ /* For a pointer array address as:
+ .ACCESS_WITH_SIZE (p->c, &p->b, 1, 0, -1, 0B)
+ + (sizetype) ((long unsigned int) index * 4)
+ op0 is the call to .ACCESS_WITH_SIZE;
+ op1 is the index. */
+ if (TREE_CODE (expr) != POINTER_PLUS_EXPR)
+ return false;
+
+ tree op0 = TREE_OPERAND (expr, 0);
+ if (!is_access_with_size_p (op0))
+ return false;
+ tree op1 = get_index_from_pointer_addr_expr (expr, index_p, index_n);
+ if (op1 != NULL_TREE)
+ {
+ *base = op0;
+ *index = op1;
+ return true;
+ }
+ return false;
+}
+
+/* Return true iff T is an array or an indirect reference that was
+ instrumented by SANITIZE_BOUNDS. */
bool
-ubsan_array_ref_instrumented_p (const_tree t)
+ubsan_array_ref_instrumented_p (tree t)
{
- if (TREE_CODE (t) != ARRAY_REF)
+ if (TREE_CODE (t) != ARRAY_REF
+ && TREE_CODE (t) != MEM_REF)
return false;
- tree op1 = TREE_OPERAND (t, 1);
- return TREE_CODE (op1) == COMPOUND_EXPR
- && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
- && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
- && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
+ bool is_array = (TREE_CODE (t) == ARRAY_REF);
+ tree op0 = NULL_TREE;
+ tree op1 = NULL_TREE;
+ tree index_p = NULL_TREE;
+ int index_n = 0;
+ if (is_array)
+ {
+ op1 = TREE_OPERAND (t, 1);
+ return TREE_CODE (op1) == COMPOUND_EXPR
+ && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
+ && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
+ && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
+ }
+ else if (is_instrumentable_pointer_array_address (t, &op0, &op1,
+ &index_p, &index_n))
+ return TREE_CODE (op1) == COMPOUND_EXPR
+ && TREE_CODE (TREE_OPERAND (op1, 0)) == CALL_EXPR
+ && CALL_EXPR_FN (TREE_OPERAND (op1, 0)) == NULL_TREE
+ && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS;
+
+ return false;
}
-/* Instrument an ARRAY_REF, if it hasn't already been instrumented.
- IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
+/* Instrument an ARRAY_REF or an address computation whose base address is
+ a call to .ACCESS_WITH_SIZE, if it hasn't already been instrumented.
+ IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR, or the
+ address computation is not inside a INDIRECT_REF. */
void
ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
{
+ tree e = NULL_TREE;
+ tree op0 = NULL_TREE;
+ tree op1 = NULL_TREE;
+ tree index_p = NULL_TREE; /* the parent tree of INDEX. */
+ int index_n = 0; /* the operand position of INDEX in the parent tree. */
+
if (!ubsan_array_ref_instrumented_p (*expr_p)
&& sanitize_flags_p (SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT)
&& current_function_decl != NULL_TREE)
{
- tree op0 = TREE_OPERAND (*expr_p, 0);
- tree op1 = TREE_OPERAND (*expr_p, 1);
- tree e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0, &op1,
- ignore_off_by_one);
+ if (TREE_CODE (*expr_p) == ARRAY_REF)
+ {
+ op0 = TREE_OPERAND (*expr_p, 0);
+ op1 = TREE_OPERAND (*expr_p, 1);
+ index_p = *expr_p;
+ index_n = 1;
+ e = ubsan_instrument_bounds (EXPR_LOCATION (*expr_p), op0,
+ &op1, ignore_off_by_one);
+ }
+ else if (is_instrumentable_pointer_array_address (*expr_p, &op0, &op1,
+ &index_p, &index_n))
+ e = ubsan_instrument_bounds_pointer_address (EXPR_LOCATION (*expr_p),
+ op0, &op1,
+ ignore_off_by_one);
+
+ /* Replace the original INDEX with the instrumented INDEX. */
if (e != NULL_TREE)
- TREE_OPERAND (*expr_p, 1) = build2 (COMPOUND_EXPR, TREE_TYPE (op1),
- e, op1);
+ TREE_OPERAND (index_p, index_n)
+ = build2 (COMPOUND_EXPR, TREE_TYPE (op1), e, op1);
}
}
diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index d547b08..5eb735e 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -3425,349 +3425,363 @@ expr_to_str (pretty_printer &pp, tree expr, const char *dflt)
return pp_formatted_text (&pp);
}
-/* Detect and diagnose a mismatch between an attribute access specification
- on the original declaration of FNDECL and that on the parameters NEWPARMS
- from its redeclaration. ORIGLOC is the location of the first declaration
- (FNDECL's is set to the location of the redeclaration). */
+/* Helper for warn_parms_array_mismatch. Compare the mappings of
+ two function parameters and diagnose mismatches. ORIGLOC is the
+ location of the first function declaration. CURP and NEWP are the
+ parameters in the first and second function declarators,
+ respectively. PARMPOS is the position of the parameters within the
+ list of parameter declarations. BUILTIN is true if the function is
+ a builtin. */
-void
-warn_parm_array_mismatch (location_t origloc, tree fndecl, tree newparms)
+static void
+warn_parm_array_mismatch (location_t origloc, rdwr_map *cur_idx,
+ rdwr_map *new_idx, tree curp, tree newp,
+ unsigned parmpos, bool builtin)
{
- /* The original parameter list (copied from the original declaration
- into the current [re]declaration, FNDECL)). The two are equal if
- and only if FNDECL is the first declaration. */
- tree curparms = DECL_ARGUMENTS (fndecl);
- if (!curparms || !newparms || curparms == newparms)
+ /* Create an empty access specification and use it for pointers with
+ no spec of their own. */
+ attr_access ptr_spec = { };
+
+ /* Only check pointers and C++ references. */
+ tree curptype = TREE_TYPE (curp);
+ tree newptype = TREE_TYPE (newp);
+ if (!POINTER_TYPE_P (curptype) || !POINTER_TYPE_P (newptype))
return;
- if (TREE_CODE (curparms) != PARM_DECL
- || TREE_CODE (newparms) != PARM_DECL)
+ /* Skip mismatches in __builtin_va_list that is commonly
+ an array but that in declarations of built-ins decays
+ to a pointer. */
+ if (builtin && TREE_TYPE (newptype) == TREE_TYPE (va_list_type_node))
return;
- /* Extract the (possibly empty) attribute access specification from
- the declaration and its type (it doesn't yet reflect those created
- in response to NEWPARMS). */
- rdwr_map cur_idx;
- tree fntype = TREE_TYPE (fndecl);
- init_attr_rdwr_indices (&cur_idx, TYPE_ATTRIBUTES (fntype));
- /* Build a (possibly null) chain of access attributes corresponding
- to NEWPARMS. */
- const bool builtin = fndecl_built_in_p (fndecl);
- tree newattrs = build_attr_access_from_parms (newparms, builtin);
+ /* Access specs for the argument on the current (previous) and
+ new (to replace the current) declarations. Either may be null,
+ indicating the parameter is an ordinary pointer with no size
+ associated with it. */
+ attr_access *cura = cur_idx->get (parmpos);
+ attr_access *newa = new_idx->get (parmpos);
- /* Extract the (possibly empty) attribute access specification from
- NEWATTRS. */
- rdwr_map new_idx;
- init_attr_rdwr_indices (&new_idx, newattrs);
+ if (!newa)
+ {
+ /* Continue if both parameters are pointers with no size
+ associated with them. */
+ if (!cura)
+ return;
- if (cur_idx.is_empty () && new_idx.is_empty ())
+ /* Otherwise point at PTR_SPEC and set its parameter pointer
+ and number. */
+ newa = &ptr_spec;
+ newa->ptr = newp;
+ newa->ptrarg = parmpos;
+ }
+ else if (!cura)
{
- /* If both specs are empty check pointers to VLAs for mismatches. */
- warn_parm_ptrarray_mismatch (origloc, curparms, newparms);
- return;
+ cura = &ptr_spec;
+ cura->ptr = curp;
+ cura->ptrarg = parmpos;
}
- /* ...otherwise, if at least one spec isn't empty there may be mismatches,
- such as between f(T*) and f(T[1]), where the former mapping would be
- empty. */
-
- /* Create an empty access specification and use it for pointers with
- no spec of their own. */
- attr_access ptr_spec = { };
- /* Iterate over the two lists of function parameters, comparing their
- respective mappings and diagnosing mismatches. */
- unsigned parmpos = 0;
- for (tree curp = curparms, newp = newparms; curp;
- curp = TREE_CHAIN (curp), newp = TREE_CHAIN (newp), ++parmpos)
- {
- if (!newp)
- /* Bail on invalid redeclarations with fewer arguments. */
- return;
+ /* Set if the parameter is [re]declared as a VLA. */
+ const bool cur_vla_p = cura->size || cura->minsize == HOST_WIDE_INT_M1U;
+ const bool new_vla_p = newa->size || newa->minsize == HOST_WIDE_INT_M1U;
- /* Only check pointers and C++ references. */
- tree curptype = TREE_TYPE (curp);
- tree newptype = TREE_TYPE (newp);
- if (!POINTER_TYPE_P (curptype) || !POINTER_TYPE_P (newptype))
- continue;
+ if (DECL_P (curp))
+ origloc = DECL_SOURCE_LOCATION (curp);
+ else if (EXPR_P (curp) && EXPR_HAS_LOCATION (curp))
+ origloc = EXPR_LOCATION (curp);
- /* Skip mismatches in __builtin_va_list that is commonly
- an array but that in declarations of built-ins decays
- to a pointer. */
- if (builtin && TREE_TYPE (newptype) == TREE_TYPE (va_list_type_node))
- continue;
+ /* The location of the parameter in the current redeclaration. */
+ location_t newloc = DECL_SOURCE_LOCATION (newp);
+ if (origloc == UNKNOWN_LOCATION)
+ origloc = newloc;
- /* Access specs for the argument on the current (previous) and
- new (to replace the current) declarations. Either may be null,
- indicating the parameter is an ordinary pointer with no size
- associated with it. */
- attr_access *cura = cur_idx.get (parmpos);
- attr_access *newa = new_idx.get (parmpos);
+ const std::string newparmstr = newa->array_as_string (newptype);
+ const std::string curparmstr = cura->array_as_string (curptype);
+ if (new_vla_p && !cur_vla_p)
+ {
+ if (warning_at (newloc, OPT_Wvla_parameter,
+ "argument %u of type %s "
+ "declared as a variable length array",
+ parmpos + 1, newparmstr.c_str ()))
+ inform (origloc,
+ (cura == &ptr_spec
+ ? G_("previously declared as a pointer %s")
+ : G_("previously declared as an ordinary array %s")),
+ curparmstr.c_str ());
+ return;
+ }
- if (!newa)
+ if (newa == &ptr_spec)
+ {
+ /* The new declaration uses the pointer form. Detect mismatches
+ between the pointer and a previous array or VLA forms. */
+ if (cura->minsize == HOST_WIDE_INT_M1U)
{
- /* Continue of both parameters are pointers with no size
- associated with it. */
- if (!cura)
- continue;
-
- /* Otherwise point at PTR_SPEC and set its parameter pointer
- and number. */
- newa = &ptr_spec;
- newa->ptr = newp;
- newa->ptrarg = parmpos;
+ /* Diagnose a pointer/VLA mismatch. */
+ if (warning_at (newloc, OPT_Wvla_parameter,
+ "argument %u of type %s declared as a pointer",
+ parmpos + 1, newparmstr.c_str ()))
+ inform (origloc,
+ "previously declared as a variable length array %s",
+ curparmstr.c_str ());
+ return;
}
- else if (!cura)
+
+ if (cura->minsize && cura->minsize != HOST_WIDE_INT_M1U)
{
- cura = &ptr_spec;
- cura->ptr = curp;
- cura->ptrarg = parmpos;
+ /* Diagnose mismatches between arrays with a constant
+ bound and pointers. */
+ if (warning_at (newloc, OPT_Warray_parameter_,
+ "argument %u of type %s declared as a pointer",
+ parmpos + 1, newparmstr.c_str ()))
+ inform (origloc, "previously declared as an array %s",
+ curparmstr.c_str ());
+ return;
}
+ }
- /* Set if the parameter is [re]declared as a VLA. */
- const bool cur_vla_p = cura->size || cura->minsize == HOST_WIDE_INT_M1U;
- const bool new_vla_p = newa->size || newa->minsize == HOST_WIDE_INT_M1U;
+ if (!new_vla_p && cur_vla_p)
+ {
+ if (warning_at (newloc, OPT_Wvla_parameter,
+ "argument %u of type %s declared as an ordinary array",
+ parmpos + 1, newparmstr.c_str ()))
+ inform (origloc, "previously declared as a variable length array %s",
+ curparmstr.c_str ());
+ return;
+ }
- if (DECL_P (curp))
- origloc = DECL_SOURCE_LOCATION (curp);
- else if (EXPR_P (curp) && EXPR_HAS_LOCATION (curp))
- origloc = EXPR_LOCATION (curp);
+ /* Move on to the next pair of parameters if both of the current
+ pair are VLAs with a single variable bound that refers to
+ a parameter at the same position. */
+ if (newa->size && cura->size
+ && newa->sizarg != UINT_MAX
+ && newa->sizarg == cura->sizarg
+ && newa->minsize == cura->minsize
+ && !TREE_PURPOSE (newa->size) && !TREE_PURPOSE (cura->size))
+ return;
- /* The location of the parameter in the current redeclaration. */
- location_t newloc = DECL_SOURCE_LOCATION (newp);
- if (origloc == UNKNOWN_LOCATION)
- origloc = newloc;
+ if (newa->size || cura->size)
+ {
+ unsigned newunspec, curunspec;
+ unsigned newbnds = newa->vla_bounds (&newunspec) + newunspec;
+ unsigned curbnds = cura->vla_bounds (&curunspec) + curunspec;
- const std::string newparmstr = newa->array_as_string (newptype);
- const std::string curparmstr = cura->array_as_string (curptype);
- if (new_vla_p && !cur_vla_p)
+ if (newbnds != curbnds)
{
- if (warning_at (newloc, OPT_Wvla_parameter,
- "argument %u of type %s declared as "
- "a variable length array",
- parmpos + 1, newparmstr.c_str ()))
- inform (origloc,
- (cura == &ptr_spec
- ? G_("previously declared as a pointer %s")
- : G_("previously declared as an ordinary array %s")),
- curparmstr.c_str ());
- continue;
+ if (warning_n (newloc, OPT_Wvla_parameter, newbnds,
+ "argument %u of type %s declared with "
+ "%u variable bound",
+ "argument %u of type %s declared with "
+ "%u variable bounds",
+ parmpos + 1, newparmstr.c_str (),
+ newbnds))
+ inform_n (origloc, curbnds,
+ "previously declared as %s with %u variable bound",
+ "previously declared as %s with %u variable bounds",
+ curparmstr.c_str (), curbnds);
+ return;
}
- if (newa == &ptr_spec)
+ if (newunspec > curunspec)
{
- /* The new declaration uses the pointer form. Detect mismatches
- between the pointer and a previous array or VLA forms. */
- if (cura->minsize == HOST_WIDE_INT_M1U)
- {
- /* Diagnose a pointer/VLA mismatch. */
- if (warning_at (newloc, OPT_Wvla_parameter,
- "argument %u of type %s declared "
- "as a pointer",
- parmpos + 1, newparmstr.c_str ()))
- inform (origloc,
- "previously declared as a variable length array %s",
- curparmstr.c_str ());
- continue;
- }
-
- if (cura->minsize && cura->minsize != HOST_WIDE_INT_M1U)
+ location_t warnloc = newloc, noteloc = origloc;
+ const char *warnparmstr = newparmstr.c_str ();
+ const char *noteparmstr = curparmstr.c_str ();
+ unsigned warnunspec = newunspec, noteunspec = curunspec;
+
+ if (warning_n (warnloc, OPT_Wvla_parameter, warnunspec,
+ "argument %u of type %s declared with "
+ "%u unspecified variable bound",
+ "argument %u of type %s declared with "
+ "%u unspecified variable bounds",
+ parmpos + 1, warnparmstr, warnunspec))
{
- /* Diagnose mismatches between arrays with a constant
- bound and pointers. */
- if (warning_at (newloc, OPT_Warray_parameter_,
- "argument %u of type %s declared "
- "as a pointer",
- parmpos + 1, newparmstr.c_str ()))
- inform (origloc, "previously declared as an array %s",
- curparmstr.c_str ());
- continue;
+ if (warnloc == newloc)
+ inform_n (noteloc, noteunspec,
+ "previously declared as %s with "
+ "%u unspecified variable bound",
+ "previously declared as %s with "
+ "%u unspecified variable bounds",
+ noteparmstr, noteunspec);
+ else
+ inform_n (noteloc, noteunspec,
+ "subsequently declared as %s with "
+ "%u unspecified variable bound",
+ "subsequently declared as %s with "
+ "%u unspecified variable bounds",
+ noteparmstr, noteunspec);
}
+ return;
}
+ }
- if (!new_vla_p && cur_vla_p)
- {
- if (warning_at (newloc, OPT_Wvla_parameter,
- "argument %u of type %s declared "
- "as an ordinary array",
- parmpos + 1, newparmstr.c_str ()))
- inform (origloc,
- "previously declared as a variable length array %s",
- curparmstr.c_str ());
- continue;
- }
+ /* Iterate over the lists of VLA variable bounds, comparing each
+ pair for equality, and diagnosing mismatches. */
+ for (tree newvbl = newa->size, curvbl = cura->size; newvbl && curvbl;
+ newvbl = TREE_CHAIN (newvbl), curvbl = TREE_CHAIN (curvbl))
+ {
+ tree newpos = TREE_PURPOSE (newvbl);
+ tree curpos = TREE_PURPOSE (curvbl);
- /* Move on to the next pair of parameters if both of the current
- pair are VLAs with a single variable bound that refers to
- a parameter at the same position. */
- if (newa->size && cura->size
- && newa->sizarg != UINT_MAX
- && newa->sizarg == cura->sizarg
- && newa->minsize == cura->minsize
- && !TREE_PURPOSE (newa->size) && !TREE_PURPOSE (cura->size))
+ tree newbnd = vla_bound_parm_decl (TREE_VALUE (newvbl));
+ tree curbnd = vla_bound_parm_decl (TREE_VALUE (curvbl));
+
+ if (newpos == curpos && newbnd == curbnd)
+ /* In the expected case when both bounds either refer to
+ the same positional parameter or when neither does,
+ and both are the same expression they are necessarily
+ the same. */
continue;
- if (newa->size || cura->size)
- {
- unsigned newunspec, curunspec;
- unsigned newbnds = newa->vla_bounds (&newunspec) + newunspec;
- unsigned curbnds = cura->vla_bounds (&curunspec) + curunspec;
+ pretty_printer pp1, pp2;
+ const char* const newbndstr = expr_to_str (pp1, newbnd, "*");
+ const char* const curbndstr = expr_to_str (pp2, curbnd, "*");
- if (newbnds != curbnds)
+ if (!newpos != !curpos
+ || (newpos && !tree_int_cst_equal (newpos, curpos)))
+ {
+ /* Diagnose a mismatch between a specified VLA bound and
+ an unspecified one. This can only happen in the most
+ significant bound.
+
+ Distinguish between the common case of bounds that are
+ other function parameters such as in
+ f (int n, int[n]);
+ and others. */
+
+ gcc_rich_location richloc (newloc);
+ bool warned;
+ if (newpos)
{
- if (warning_n (newloc, OPT_Wvla_parameter, newbnds,
- "argument %u of type %s declared with "
- "%u variable bound",
- "argument %u of type %s declared with "
- "%u variable bounds",
- parmpos + 1, newparmstr.c_str (),
- newbnds))
- inform_n (origloc, curbnds,
- "previously declared as %s with %u variable bound",
- "previously declared as %s with %u variable bounds",
- curparmstr.c_str (), curbnds);
- continue;
+ /* Also underline the VLA bound argument. */
+ richloc.add_range (DECL_SOURCE_LOCATION (newbnd));
+ warned = warning_at (&richloc, OPT_Wvla_parameter,
+ "argument %u of type %s "
+ "declared with mismatched bound argument %E",
+ parmpos + 1, newparmstr.c_str (),
+ plus_one (newpos));
}
+ else
+ warned = warning_at (&richloc, OPT_Wvla_parameter,
+ "argument %u of type %s "
+ "declared with mismatched bound %qs",
+ parmpos + 1, newparmstr.c_str (),
+ newbndstr);
- if (newunspec > curunspec)
+ if (warned)
{
- location_t warnloc = newloc, noteloc = origloc;
- const char *warnparmstr = newparmstr.c_str ();
- const char *noteparmstr = curparmstr.c_str ();
- unsigned warnunspec = newunspec, noteunspec = curunspec;
-
- if (warning_n (warnloc, OPT_Wvla_parameter, warnunspec,
- "argument %u of type %s declared with "
- "%u unspecified variable bound",
- "argument %u of type %s declared with "
- "%u unspecified variable bounds",
- parmpos + 1, warnparmstr, warnunspec))
+ gcc_rich_location richloc (origloc);
+ if (curpos)
{
- if (warnloc == newloc)
- inform_n (noteloc, noteunspec,
- "previously declared as %s with %u unspecified "
- "variable bound",
- "previously declared as %s with %u unspecified "
- "variable bounds",
- noteparmstr, noteunspec);
- else
- inform_n (noteloc, noteunspec,
- "subsequently declared as %s with %u unspecified "
- "variable bound",
- "subsequently declared as %s with %u unspecified "
- "variable bounds",
- noteparmstr, noteunspec);
+ /* Also underline the VLA bound argument. */
+ richloc.add_range (DECL_SOURCE_LOCATION (curbnd));
+ inform (&richloc,
+ "previously declared as %s with bound argument %E",
+ curparmstr.c_str (), plus_one (curpos));
}
+ else
+ inform (&richloc,
+ "previously declared as %s with bound %qs",
+ curparmstr.c_str (), curbndstr);
+
continue;
}
}
- /* Iterate over the lists of VLA variable bounds, comparing each
- pair for equality, and diagnosing mismatches. */
- for (tree newvbl = newa->size, curvbl = cura->size; newvbl && curvbl;
- newvbl = TREE_CHAIN (newvbl), curvbl = TREE_CHAIN (curvbl))
+ if (!newpos && newbnd && curbnd)
{
- tree newpos = TREE_PURPOSE (newvbl);
- tree curpos = TREE_PURPOSE (curvbl);
+ /* The VLA bounds don't refer to other function parameters.
+ Compare them lexicographically to detect gross mismatches
+ such as between T[foo()] and T[bar()]. */
+ if (operand_equal_p (newbnd, curbnd,
+ OEP_DECL_NAME | OEP_LEXICOGRAPHIC))
+ continue;
- tree newbnd = vla_bound_parm_decl (TREE_VALUE (newvbl));
- tree curbnd = vla_bound_parm_decl (TREE_VALUE (curvbl));
+ if (warning_at (newloc, OPT_Wvla_parameter,
+ "argument %u of type %s "
+ "declared with mismatched bound %qs",
+ parmpos + 1, newparmstr.c_str (), newbndstr))
+ inform (origloc, "previously declared as %s with bound %qs",
+ curparmstr.c_str (), curbndstr);
+ continue;
+ }
+ }
- if (newpos == curpos && newbnd == curbnd)
- /* In the expected case when both bounds either refer to
- the same positional parameter or when neither does,
- and both are the same expression they are necessarily
- the same. */
- continue;
+ if (newa->minsize == cura->minsize
+ || (((newa->minsize == 0 && newa->mode != access_deferred)
+ || (cura->minsize == 0 && cura->mode != access_deferred))
+ && newa != &ptr_spec
+ && cura != &ptr_spec))
+ return;
- pretty_printer pp1, pp2;
- const char* const newbndstr = expr_to_str (pp1, newbnd, "*");
- const char* const curbndstr = expr_to_str (pp2, curbnd, "*");
+ if (!newa->static_p && !cura->static_p && warn_array_parameter < 2)
+ /* Avoid warning about mismatches in ordinary (non-static) arrays
+ at levels below 2. */
+ return;
- if (!newpos != !curpos
- || (newpos && !tree_int_cst_equal (newpos, curpos)))
- {
- /* Diagnose a mismatch between a specified VLA bound and
- an unspecified one. This can only happen in the most
- significant bound.
-
- Distinguish between the common case of bounds that are
- other function parameters such as in
- f (int n, int[n]);
- and others. */
-
- gcc_rich_location richloc (newloc);
- bool warned;
- if (newpos)
- {
- /* Also underline the VLA bound argument. */
- richloc.add_range (DECL_SOURCE_LOCATION (newbnd));
- warned = warning_at (&richloc, OPT_Wvla_parameter,
- "argument %u of type %s declared "
- "with mismatched bound argument %E",
- parmpos + 1, newparmstr.c_str (),
- plus_one (newpos));
- }
- else
- warned = warning_at (&richloc, OPT_Wvla_parameter,
- "argument %u of type %s declared "
- "with mismatched bound %qs",
- parmpos + 1, newparmstr.c_str (),
- newbndstr);
+ if (warning_at (newloc, OPT_Warray_parameter_,
+ "argument %u of type %s with mismatched bound",
+ parmpos + 1, newparmstr.c_str ()))
+ inform (origloc, "previously declared as %s", curparmstr.c_str ());
+}
- if (warned)
- {
- gcc_rich_location richloc (origloc);
- if (curpos)
- {
- /* Also underline the VLA bound argument. */
- richloc.add_range (DECL_SOURCE_LOCATION (curbnd));
- inform (&richloc, "previously declared as %s with "
- "bound argument %E",
- curparmstr.c_str (), plus_one (curpos));
- }
- else
- inform (&richloc, "previously declared as %s with bound "
- "%qs", curparmstr.c_str (), curbndstr);
+/* Detect and diagnose a mismatch between an attribute access specification
+ on the original declaration of FNDECL and that on the parameters NEWPARMS
+ from its redeclaration. ORIGLOC is the location of the first declaration
+ (FNDECL's is set to the location of the redeclaration). */
- continue;
- }
- }
+void
+warn_parms_array_mismatch (location_t origloc, tree fndecl, tree newparms)
+{
+ /* The original parameter list (copied from the original declaration
+ into the current [re]declaration, FNDECL)). The two are equal if
+ and only if FNDECL is the first declaration. */
+ tree curparms = DECL_ARGUMENTS (fndecl);
+ if (!curparms || !newparms || curparms == newparms)
+ return;
- if (!newpos && newbnd && curbnd)
- {
- /* The VLA bounds don't refer to other function parameters.
- Compare them lexicographically to detect gross mismatches
- such as between T[foo()] and T[bar()]. */
- if (operand_equal_p (newbnd, curbnd,
- OEP_DECL_NAME | OEP_LEXICOGRAPHIC))
- continue;
-
- if (warning_at (newloc, OPT_Wvla_parameter,
- "argument %u of type %s declared with "
- "mismatched bound %qs",
- parmpos + 1, newparmstr.c_str (), newbndstr))
- inform (origloc, "previously declared as %s with bound %qs",
- curparmstr.c_str (), curbndstr);
- continue;
- }
- }
+ if (TREE_CODE (curparms) != PARM_DECL
+ || TREE_CODE (newparms) != PARM_DECL)
+ return;
+ /* Extract the (possibly empty) attribute access specification from
+ the declaration and its type (it doesn't yet reflect those created
+ in response to NEWPARMS). */
+ rdwr_map cur_idx;
+ tree fntype = TREE_TYPE (fndecl);
+ init_attr_rdwr_indices (&cur_idx, TYPE_ATTRIBUTES (fntype));
- if (newa->minsize == cura->minsize
- || (((newa->minsize == 0 && newa->mode != access_deferred)
- || (cura->minsize == 0 && cura->mode != access_deferred))
- && newa != &ptr_spec
- && cura != &ptr_spec))
- continue;
+ /* Build a (possibly null) chain of access attributes corresponding
+ to NEWPARMS. */
+ const bool builtin = fndecl_built_in_p (fndecl);
+ tree newattrs = build_attr_access_from_parms (newparms, builtin);
- if (!newa->static_p && !cura->static_p && warn_array_parameter < 2)
- /* Avoid warning about mismatches in ordinary (non-static) arrays
- at levels below 2. */
- continue;
+ /* Extract the (possibly empty) attribute access specification from
+ NEWATTRS. */
+ rdwr_map new_idx;
+ init_attr_rdwr_indices (&new_idx, newattrs);
- if (warning_at (newloc, OPT_Warray_parameter_,
- "argument %u of type %s with mismatched bound",
- parmpos + 1, newparmstr.c_str ()))
- inform (origloc, "previously declared as %s", curparmstr.c_str ());
+ if (cur_idx.is_empty () && new_idx.is_empty ())
+ {
+ /* If both specs are empty check pointers to VLAs for mismatches. */
+ warn_parm_ptrarray_mismatch (origloc, curparms, newparms);
+ return;
+ }
+ /* ...otherwise, if at least one spec isn't empty there may be mismatches,
+ such as between f(T*) and f(T[1]), where the former mapping would be
+ empty. */
+
+ /* Iterate over the two lists of function parameters, comparing their
+ respective mappings and diagnosing mismatches. */
+ unsigned parmpos = 0;
+ for (tree curp = curparms, newp = newparms; curp;
+ curp = TREE_CHAIN (curp), newp = TREE_CHAIN (newp), ++parmpos)
+ {
+ if (!newp)
+ /* Bail on invalid redeclarations with fewer arguments. */
+ return;
+
+ warn_parm_array_mismatch (origloc, &cur_idx, &new_idx, curp, newp, parmpos,
+ builtin);
}
}
@@ -3835,7 +3849,7 @@ do_warn_array_compare (location_t location, tree_code code, tree op0, tree op1)
op1 = TREE_OPERAND (op1, 0);
auto_diagnostic_group d;
- diagnostic_t kind = DK_WARNING;
+ enum diagnostics::kind kind = diagnostics::kind::warning;
const char *msg;
if (c_dialect_cxx () && cxx_dialect >= cxx20)
{
@@ -3843,7 +3857,7 @@ do_warn_array_compare (location_t location, tree_code code, tree op0, tree op1)
if (cxx_dialect >= cxx26)
{
msg = G_("comparison between two arrays is not allowed in C++26");
- kind = DK_PERMERROR;
+ kind = diagnostics::kind::permerror;
}
else
msg = G_("comparison between two arrays is deprecated in C++20");
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 75b6531..e1576c9 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -45,6 +45,10 @@ C ObjC C++ ObjC++ Separate Alias(A) MissingArgError(assertion missing after %qs)
-assert=
C ObjC C++ ObjC++ Joined Alias(A) MissingArgError(assertion missing after %qs)
+-compile-std-module
+C++ ObjC++ Driver
+--compile-std-module Compile module units for <bits/stdc++.h>, std, and std.compat.
+
-comments
C ObjC C++ ObjC++ Alias(C)
@@ -267,15 +271,15 @@ C ObjC C++ ObjC++ Joined Separate MissingArgError(missing makefile target after
-MT <target> Add a target that does not require quoting.
fdeps-format=
-C ObjC C++ ObjC++ NoDriverArg Joined MissingArgError(missing format after %qs)
+C ObjC C++ ObjC++ RejectNegative Joined MissingArgError(missing format after %qs)
Structured format for output dependency information. Supported (\"p1689r5\").
fdeps-file=
-C ObjC C++ ObjC++ NoDriverArg Joined MissingArgError(missing output path after %qs)
+C ObjC C++ ObjC++ RejectNegative Joined MissingArgError(missing output path after %qs)
File for output dependency information.
fdeps-target=
-C ObjC C++ ObjC++ NoDriverArg Joined MissingArgError(missing path after %qs)
+C ObjC C++ ObjC++ RejectNegative Joined MissingArgError(missing path after %qs)
-fdeps-target=obj.o Output file for the compile step.
P
@@ -351,12 +355,12 @@ C ObjC C++ ObjC++ Var(warn_alloc_size) Warning LangEnabledBy(C ObjC C++ ObjC++,
Warn when allocating insufficient storage for the target type of the assigned pointer.
Walloc-size-larger-than=
-C ObjC C++ LTO ObjC++ Var(warn_alloc_size_limit) Joined Host_Wide_Int ByteSize Warning Init(HOST_WIDE_INT_MAX)
+C ObjC C++ LTO ObjC++ Var(warn_alloc_size_limit) Joined RejectNegative Host_Wide_Int ByteSize Warning Init(HOST_WIDE_INT_MAX)
-Walloc-size-larger-than=<bytes> Warn for calls to allocation functions that
attempt to allocate objects larger than the specified number of bytes.
Wno-alloc-size-larger-than
-C ObjC C++ LTO ObjC++ Alias(Walloc-size-larger-than=,18446744073709551615EiB,none) Warning
+C ObjC C++ LTO ObjC++ RejectNegative Alias(Walloc-size-larger-than=,18446744073709551615EiB,none) Warning
Disable Walloc-size-larger-than= warning. Equivalent to Walloc-size-larger-than=<SIZE_MAX> or larger.
Walloc-zero
@@ -364,13 +368,13 @@ C ObjC C++ ObjC++ Var(warn_alloc_zero) Warning
Warn for calls to allocation functions that specify zero bytes.
Walloca-larger-than=
-C ObjC C++ LTO ObjC++ Var(warn_alloca_limit) Warning Joined Host_Wide_Int ByteSize Init(HOST_WIDE_INT_MAX)
+C ObjC C++ LTO ObjC++ Var(warn_alloca_limit) Warning Joined RejectNegative Host_Wide_Int ByteSize Init(HOST_WIDE_INT_MAX)
-Walloca-larger-than=<number> Warn on unbounded uses of
alloca, and on bounded uses of alloca whose bound can be larger than
<number> bytes.
Wno-alloca-larger-than
-C ObjC C++ LTO ObjC++ Alias(Walloca-larger-than=,18446744073709551615EiB,none) Warning
+C ObjC C++ LTO ObjC++ RejectNegative Alias(Walloca-larger-than=,18446744073709551615EiB,none) Warning
Disable Walloca-larger-than= warning. Equivalent to Walloca-larger-than=<SIZE_MAX> or larger.
Warith-conversion
@@ -397,6 +401,10 @@ Wassign-intercept
ObjC ObjC++ Var(warn_assign_intercept) Warning
Warn whenever an Objective-C assignment is being intercepted by the garbage collector.
+Wabbreviated-auto-in-template-arg
+C++ ObjC++ Warning Var(warn_abbev_auto_targ) Init(1)
+Diagnose a placeholder type in a template argument in a function parameter type.
+
Wbad-function-cast
C ObjC Var(warn_bad_function_cast) Warning
Warn about casting functions to incompatible types.
@@ -493,6 +501,10 @@ Wc++20-compat
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++26-compat
+C++ ObjC++ Var(warn_cxx26_compat) Warning LangEnabledBy(C++ ObjC++,Wall) Init(0)
+Warn about C++ constructs whose meaning differs between ISO C++ 2023 and ISO C++ 2026.
+
Wc++11-extensions
C++ ObjC++ Var(warn_cxx11_extensions) Warning Init(1)
Warn about C++11 constructs in code compiled with an older standard.
@@ -753,6 +765,14 @@ Wexpansion-to-defined
C ObjC C++ ObjC++ CPP(warn_expansion_to_defined) CppReason(CPP_W_EXPANSION_TO_DEFINED) Var(cpp_warn_expansion_to_defined) Init(0) Warning EnabledBy(Wextra || Wpedantic)
Warn if \"defined\" is used outside #if.
+Wexternal-tu-local
+C++ ObjC++ Var(warn_tu_local) Warning Init(1)
+Warn about naming a TU-local entity declared in another translation unit.
+
+Wexpose-global-module-tu-local
+C++ ObjC++ Var(warn_expose_global_module_tu_local) Init(1) Warning
+Warn when a module exposes a TU-local entity from the global module fragment.
+
Wextra
C ObjC C++ ObjC++ Warning
; in common.opt
@@ -762,7 +782,7 @@ C++ ObjC++ Var(warn_extra_semi) Init(-1) Warning
Warn about semicolon after in-class function definition.
Wflex-array-member-not-at-end
-C C++ Var(warn_flex_array_member_not_at_end) Warning
+C ObjC C++ ObjC++ Var(warn_flex_array_member_not_at_end) Warning
Warn when a structure containing a C99 flexible array member as the last
field is not at the end of another structure.
@@ -854,11 +874,11 @@ C ObjC C++ ObjC++ Var(warn_if_not_aligned) Init(1) Warning
Warn when the field in a struct is not aligned.
Wignored-qualifiers
-C C++ Var(warn_ignored_qualifiers) Warning EnabledBy(Wextra)
+C ObjC C++ ObjC++ Var(warn_ignored_qualifiers) Warning EnabledBy(Wextra)
Warn whenever type qualifiers are ignored.
Wignored-attributes
-C C++ Var(warn_ignored_attributes) Init(1) Warning
+C ObjC C++ ObjC++ Var(warn_ignored_attributes) Init(1) Warning
Warn whenever attributes are ignored.
Wimplicit
@@ -938,7 +958,7 @@ C ObjC C++ ObjC++ CPP(cpp_warn_invalid_utf8) CppReason(CPP_W_INVALID_UTF8) Var(w
Warn about invalid UTF-8 characters.
Wjump-misses-init
-C ObjC Var(warn_jump_misses_init) Warning LangEnabledby(C ObjC,Wc++-compat)
+C ObjC Var(warn_jump_misses_init) Warning LangEnabledBy(C ObjC,Wc++-compat)
Warn when a jump misses a variable initialization.
Enum
@@ -956,6 +976,10 @@ Enum(warn_leading_whitespace_kind) String(tabs) Value(2)
EnumValue
Enum(warn_leading_whitespace_kind) String(blanks) Value(3)
+Wkeyword-macro
+C ObjC C++ ObjC++ CPP(cpp_warn_keyword_macro) CppReason(CPP_W_KEYWORD_MACRO) Var(warn_keyword_macro) Init(0) Warning
+Warn about defining or undefining macros with identifiers equal to keywords (or for C++ conditional keywords or standard attribute names).
+
Wleading-whitespace=
C ObjC C++ ObjC++ CPP(cpp_warn_leading_whitespace) CppReason(CPP_W_LEADING_WHITESPACE) Enum(warn_leading_whitespace_kind) Joined RejectNegative Var(warn_leading_whitespace) Init(0) Warning
Warn about leading whitespace style issues on lines except when in raw string literals.
@@ -997,7 +1021,7 @@ C ObjC C++ ObjC++ Var(warn_memset_transposed_args) Warning LangEnabledBy(C ObjC
Warn about suspicious calls to memset where the third argument is constant literal zero and the second is not.
Wmisleading-indentation
-C C++ Common Var(warn_misleading_indentation) Warning LangEnabledBy(C C++,Wall)
+C ObjC C++ ObjC++ Common Var(warn_misleading_indentation) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn when the indentation of the code does not reflect the block structure.
Wmismatched-dealloc
@@ -1074,6 +1098,10 @@ Wmultiple-inheritance
C++ ObjC++ Var(warn_multiple_inheritance) Warning
Warn on direct multiple inheritance.
+Wmultiple-parameter-fwd-decl-lists
+C ObjC Var(warn_multiple_parameter_fwd_decl_lists) Warning EnabledBy(Wextra)
+Warn for multiple lists of forward declarations of function parameters.
+
Wmultistatement-macros
C ObjC C++ ObjC++ Var(warn_multistatement_macros) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn about unsafe macros expanding to multiple statements used as a body of a clause such as if, else, while, switch, or for.
@@ -1098,6 +1126,10 @@ Wnoexcept-type
C++ ObjC++ Warning Var(warn_noexcept_type) LangEnabledBy(C++ ObjC++,Wabi || Wc++17-compat)
Warn if C++17 noexcept function type will change the mangled name of a symbol.
+Wnon-c-typedef-for-linkage
+C++ ObjC++ Var(warn_non_c_typedef_for_linkage) Init(1) Warning
+Warn for non-C compatible unnamed classes with a typedef name for linkage purposes.
+
Wnon-template-friend
C++ ObjC++ Var(warn_nontemplate_friend) Init(1) Warning
Warn when non-templatized friend functions are declared within a template.
@@ -1163,7 +1195,7 @@ C ObjC Var(warn_old_style_definition) Init(-1) Warning
Warn if an old-style parameter definition is used.
Wopenacc-parallelism
-C C++ Var(warn_openacc_parallelism) Warning
+C ObjC C++ ObjC++ Var(warn_openacc_parallelism) Warning
Warn about potentially suboptimal choices related to OpenACC parallelism.
Wopenmp
@@ -1171,7 +1203,7 @@ C ObjC C++ ObjC++ Warning Var(warn_openmp) Init(1)
Warn about suspicious OpenMP code.
Wopenmp-simd
-C C++ Var(warn_openmp_simd) Warning LangEnabledBy(C C++,Wall)
+C ObjC C++ ObjC++ Var(warn_openmp_simd) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn if a simd directive is overridden by the vectorizer cost model.
Woverlength-strings
@@ -1183,7 +1215,7 @@ C++ ObjC++ Warning Alias(Woverloaded-virtual=,2,0)
Warn about overloaded virtual function names.
Woverloaded-virtual=
-C++ ObjC++ Joined UInteger IntegerRange(0,2) Var(warn_overloaded_virtual) Warning LangEnabledBy(C++ ObjC++,Wall,1,0)
+C++ ObjC++ Joined RejectNegative UInteger IntegerRange(0,2) Var(warn_overloaded_virtual) Warning LangEnabledBy(C++ ObjC++,Wall,1,0)
Warn about overloaded virtual function names.
Woverride-init
@@ -1219,11 +1251,11 @@ C++ ObjC++ Var(warn_pessimizing_move) Warning LangEnabledBy(C++ ObjC++, Wall)
Warn about calling std::move on a local object in a return statement preventing copy elision.
Wplacement-new
-C++ Warning Alias(Wplacement-new=, 1, 0)
+C++ ObjC++ Warning Alias(Wplacement-new=, 1, 0)
Warn for placement new expressions with undefined behavior.
Wplacement-new=
-C++ Joined RejectNegative UInteger Var(warn_placement_new) Init(-1) Warning IntegerRange(0, 2)
+C++ ObjC++ Joined RejectNegative UInteger Var(warn_placement_new) Init(-1) Warning IntegerRange(0, 2)
Warn for placement new expressions with undefined behavior.
Wpmf-conversions
@@ -1319,6 +1351,14 @@ 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.
+Wsfinae-incomplete=
+C++ ObjC++ Var(warn_sfinae_incomplete) Warning Init(1) Joined RejectNegative UInteger IntegerRange(0, 2)
+Warn about an incomplete type affecting semantics in a non-error context.
+
+Wsfinae-incomplete
+C++ ObjC++ Warning Alias(Wsfinae-incomplete=, 1, 0)
+Warn about an incomplete type affecting semantics in a non-error context.
+
Wshadow-ivar
ObjC ObjC++ Var(warn_shadow_ivar) EnabledBy(Wshadow) Init(1) Warning
Warn if a local declaration hides an instance variable.
@@ -1385,7 +1425,7 @@ C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall, 3, 0) IntegerRange(0, 3)
;
Wstrict-flex-arrays
-C C++ Var(warn_strict_flex_arrays) Warning
+C ObjC C++ ObjC++ Var(warn_strict_flex_arrays) Warning
Warn about improper usages of flexible array members
according to the level of -fstrict-flex-arrays.
@@ -1463,12 +1503,12 @@ C ObjC C++ ObjC++ Var(warn_switch_outside_range) Warning Init(1)
Warn about switch values that are outside of the switch's type range.
Wsync-nand
-C C++ Var(warn_sync_nand) Init(1) Warning
+C ObjC C++ ObjC++ Var(warn_sync_nand) Init(1) Warning
Warn when __sync_fetch_and_nand and __sync_nand_and_fetch built-in functions are used.
Wsynth
-C++ ObjC++ Var(warn_synth) Warning
-Deprecated. This switch has no effect.
+C++ ObjC++ Warning Ignore
+Does nothing. Preserved for backward compatibility.
Wsystem-headers
C ObjC C++ ObjC++ Warning
@@ -1615,13 +1655,13 @@ C ObjC C++ ObjC++ Var(warn_vla) Init(-1) Warning
Warn if a variable length array is used.
Wvla-larger-than=
-C ObjC C++ LTO ObjC++ Var(warn_vla_limit) Warning Joined Host_Wide_Int ByteSize Init(HOST_WIDE_INT_MAX)
+C ObjC C++ LTO ObjC++ Var(warn_vla_limit) Warning Joined RejectNegative Host_Wide_Int ByteSize Init(HOST_WIDE_INT_MAX)
-Wvla-larger-than=<number> Warn on unbounded uses of variable-length
arrays, and on bounded uses of variable-length arrays whose bound can be
larger than <number> bytes.
Wno-vla-larger-than
-C ObjC C++ LTO ObjC++ Alias(Wvla-larger-than=,18446744073709551615EiB,none) Warning
+C ObjC C++ LTO ObjC++ RejectNegative Alias(Wvla-larger-than=,18446744073709551615EiB,none) Warning
Disable Wvla-larger-than= warning. Equivalent to Wvla-larger-than=<SIZE_MAX> or larger.
Wvla-parameter
@@ -1868,35 +1908,35 @@ EnumValue
Enum(on_off) String(on) Value(1)
fcontract-assumption-mode=
-C++ Joined RejectNegative
+C++ ObjC++ Joined RejectNegative
-fcontract-assumption-mode=[on|off] Enable or disable treating axiom level contracts as assumptions (default on).
fcontract-build-level=
-C++ Joined RejectNegative
+C++ ObjC++ Joined RejectNegative
-fcontract-build-level=[off|default|audit] Specify max contract level to generate runtime checks for.
fcontract-strict-declarations=
-C++ Var(flag_contract_strict_declarations) Enum(on_off) Joined Init(0) RejectNegative
+C++ ObjC++ Var(flag_contract_strict_declarations) Enum(on_off) Joined Init(0) RejectNegative
-fcontract-strict-declarations=[on|off] Enable or disable warnings on generalized redeclaration of functions with contracts (default off).
fcontract-mode=
-C++ Var(flag_contract_mode) Enum(on_off) Joined Init(1) RejectNegative
+C++ ObjC++ Var(flag_contract_mode) Enum(on_off) Joined Init(1) RejectNegative
-fcontract-mode=[on|off] Enable or disable all contract facilities (default on).
fcontract-continuation-mode=
-C++ Joined RejectNegative
+C++ ObjC++ Joined RejectNegative
-fcontract-continuation-mode=[on|off] Enable or disable contract continuation mode (default off).
fcontract-role=
-C++ Joined RejectNegative
+C++ ObjC++ Joined RejectNegative
-fcontract-role=<name>:<semantics> Specify the semantics for all levels in a role (default, review), or a custom contract role with given semantics (ex: opt:assume,assume,assume).
fcontract-semantic=
-C++ Joined RejectNegative
+C++ ObjC++ Joined RejectNegative
-fcontract-semantic=<level>:<semantic> Specify the concrete semantics for level.
fcoroutines
-C++ LTO Var(flag_coroutines)
+C++ ObjC++ LTO Var(flag_coroutines)
Enable C++ coroutines (experimental).
fdebug-cpp
@@ -2086,7 +2126,7 @@ C++ ObjC++ Var(flag_module_lazy) Init(1)
Enable lazy module importing.
fmodule-version-ignore
-C++ ObjC Var(flag_module_version_ignore) Integer
+C++ ObjC Var(flag_module_version_ignore) Integer Undocumented
; undocumented, Very dangerous, but occasionally useful
Winvalid-imported-macros
@@ -2098,23 +2138,23 @@ C ObjC Var(warn_compare_distinct_pointer_types) Warning Init(1)
Warn if pointers of distinct types are compared without a cast.
flang-info-include-translate
-C++ Var(note_include_translate_yes)
+C++ ObjC++ Var(note_include_translate_yes)
Note #include directives translated to import declarations.
flang-info-include-translate-not
-C++ Var(note_include_translate_no)
+C++ ObjC++ Var(note_include_translate_no)
Note #include directives not translated to import declarations, and not known to be textual.
flang-info-include-translate=
-C++ Joined RejectNegative MissingArgError(missing header name)
+C++ ObjC++ Joined RejectNegative MissingArgError(missing header name)
Note a #include translation of a specific header.
flang-info-module-cmi
-C++ Var(note_module_cmi_yes)
+C++ ObjC++ Var(note_module_cmi_yes)
Note Compiled Module Interface pathnames.
flang-info-module-cmi=
-C++ Joined RejectNegative MissingArgError(missing module name)
+C++ ObjC++ Joined RejectNegative MissingArgError(missing module name)
Note Compiled Module Interface pathname of a specific module or header-unit.
fmax-include-depth=
@@ -2227,7 +2267,7 @@ C ObjC C++ ObjC++ LTO Var(flag_openacc)
Enable OpenACC.
fopenacc-dim=
-C ObjC C++ ObjC++ LTO Joined Var(flag_openacc_dims)
+C ObjC C++ ObjC++ LTO Joined RejectNegative Var(flag_openacc_dims)
Specify default OpenACC compute dimensions.
fopenmp
@@ -2325,10 +2365,10 @@ C++ ObjC++ Var(flag_sized_deallocation) Init(-1)
Enable C++14 sized deallocation support.
fstrict-flex-arrays
-C C++ Common Alias(fstrict-flex-arrays=,3,0)
+C ObjC C++ ObjC++ Common Alias(fstrict-flex-arrays=,3,0)
fstrict-flex-arrays=
-C C++ Common Joined RejectNegative UInteger Var(flag_strict_flex_arrays) Init(0) IntegerRange(0,3)
+C ObjC C++ ObjC++ Common Joined RejectNegative UInteger Var(flag_strict_flex_arrays) Init(0) IntegerRange(0,3)
-fstrict-flex-arrays=<level> Control when to treat the trailing array of a structure as a flexible array member for the purposes of accessing the elements of such an array. The default is treating all trailing arrays of structures as flexible array members.
fsquangle
@@ -2458,15 +2498,15 @@ ObjC ObjC++ Driver Var(flag_gen_declaration) RejectNegative
Dump declarations to a .decl file.
femit-struct-debug-baseonly
-C ObjC C++ ObjC++
+C ObjC C++ ObjC++ RejectNegative
-femit-struct-debug-baseonly Aggressive reduced debug info for structs.
femit-struct-debug-reduced
-C ObjC C++ ObjC++
+C ObjC C++ ObjC++ RejectNegative
-femit-struct-debug-reduced Conservative reduced debug info for structs.
femit-struct-debug-detailed=
-C ObjC C++ ObjC++ Joined
+C ObjC C++ ObjC++ Joined RejectNegative
-femit-struct-debug-detailed=<spec-list> Detailed reduced debug info for structs.
fext-numeric-literals
@@ -2578,15 +2618,15 @@ Conform to the ISO 2017 C++ standard.
std=c++2a
C++ ObjC++ Alias(std=c++20) Undocumented
-Conform to the ISO 2020 C++ standard (experimental and incomplete support).
+Deprecated in favor of -std=c++20.
std=c++20
C++ ObjC++
-Conform to the ISO 2020 C++ standard (experimental and incomplete support).
+Conform to the ISO 2020 C++ standard.
std=c++2b
C++ ObjC++ Alias(std=c++23) Undocumented
-Conform to the ISO 2023 C++ standard (published in 2024; experimental and incomplete support).
+Deprecated in favor of -std=c++23.
std=c++23
C++ ObjC++
@@ -2680,15 +2720,15 @@ Conform to the ISO 2017 C++ standard with GNU extensions.
std=gnu++2a
C++ ObjC++ Alias(std=gnu++20) Undocumented
-Conform to the ISO 2020 C++ standard with GNU extensions (experimental and incomplete support).
+Deprecated in favor of -std=gnu++20.
std=gnu++20
C++ ObjC++
-Conform to the ISO 2020 C++ standard with GNU extensions (experimental and incomplete support).
+Conform to the ISO 2020 C++ standard with GNU extensions.
std=gnu++2b
C++ ObjC++ Alias(std=gnu++23) Undocumented
-Conform to the ISO 2023 C++ standard with GNU extensions (published in 2024; experimental and incomplete support).
+Deprecated in favor of -std=gnu++23.
std=gnu++23
C++ ObjC++
diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls
index ad6d8a0..9430f4b 100644
--- a/gcc/c-family/c.opt.urls
+++ b/gcc/c-family/c.opt.urls
@@ -1,8 +1,5 @@
; Autogenerated by regenerate-opt-urls.py from gcc/c-family/c.opt and generated HTML
-A
-UrlSuffix(gcc/Preprocessor-Options.html#index-A)
-
C
UrlSuffix(gcc/Preprocessor-Options.html#index-C) LangUrlSuffix_Fortran(gfortran/Preprocessing-Options.html#index-C)
@@ -26,7 +23,7 @@ H
UrlSuffix(gcc/Preprocessor-Options.html#index-H) LangUrlSuffix_D(gdc/Code-Generation.html#index-H) LangUrlSuffix_Fortran(gfortran/Preprocessing-Options.html#index-H)
I
-UrlSuffix(gcc/Directory-Options.html#index-I) LangUrlSuffix_D(gdc/Directory-Options.html#index-I)
+UrlSuffix(gcc/Directory-Options.html#index-I) LangUrlSuffix_D(gdc/Directory-Options.html#index-I) LangUrlSuffix_Algol68(ga68/Directory-options.html#index-I)
M
UrlSuffix(gcc/Preprocessor-Options.html#index-M) LangUrlSuffix_D(gdc/Code-Generation.html#index-M)
@@ -139,6 +136,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Warray-parameter)
Wassign-intercept
UrlSuffix(gcc/Objective-C-and-Objective-C_002b_002b-Dialect-Options.html#index-Wassign-intercept)
+Wabbreviated-auto-in-template-arg
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wabbreviated-auto-in-template-arg)
+
Wbad-function-cast
UrlSuffix(gcc/Warning-Options.html#index-Wbad-function-cast)
@@ -163,6 +163,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Wbuiltin-macro-redefined)
Wc11-c23-compat
UrlSuffix(gcc/Warning-Options.html#index-Wc11-c23-compat)
+Wc11-c2x-compat
+UrlSuffix(gcc/Warning-Options.html#index-Wc11-c2x-compat)
+
Wc23-c2y-compat
UrlSuffix(gcc/Warning-Options.html#index-Wc23-c2y-compat)
@@ -187,6 +190,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Wc_002b_002b17-compat)
Wc++20-compat
UrlSuffix(gcc/Warning-Options.html#index-Wc_002b_002b20-compat)
+Wc++26-compat
+UrlSuffix(gcc/Warning-Options.html#index-Wc_002b_002b26-compat)
+
Wc++11-extensions
UrlSuffix(gcc/Warning-Options.html#index-Wc_002b_002b11-extensions)
@@ -301,6 +307,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Wdeprecated) LangUrlSuffix_D(gdc/Warnin
Wdeprecated-copy
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wdeprecated-copy)
+Wdeprecated-copy-dtor
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wdeprecated-copy-dtor)
+
Wdeprecated-enum-enum-conversion
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wdeprecated-enum-enum-conversion)
@@ -370,6 +379,12 @@ UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wexceptions)
Wexpansion-to-defined
UrlSuffix(gcc/Warning-Options.html#index-Wexpansion-to-defined)
+Wexternal-tu-local
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wexternal-tu-local)
+
+Wexpose-global-module-tu-local
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wexpose-global-module-tu-local)
+
Wextra
UrlSuffix(gcc/Warning-Options.html#index-Wextra) LangUrlSuffix_D(gdc/Warnings.html#index-Wextra) LangUrlSuffix_Fortran(gfortran/Error-and-Warning-Options.html#index-Wextra)
@@ -391,6 +406,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Wformat)
Wformat-contains-nul
UrlSuffix(gcc/Warning-Options.html#index-Wformat-contains-nul)
+Wformat-diag
+UrlSuffix(gcc/Warning-Options.html#index-Wformat-diag)
+
Wformat-extra-args
UrlSuffix(gcc/Warning-Options.html#index-Wformat-extra-args)
@@ -502,6 +520,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Winvalid-utf8)
Wjump-misses-init
UrlSuffix(gcc/Warning-Options.html#index-Wjump-misses-init)
+Wkeyword-macro
+UrlSuffix(gcc/Warning-Options.html#index-Wkeyword-macro)
+
Wleading-whitespace=
UrlSuffix(gcc/Warning-Options.html#index-Wleading-whitespace_003d)
@@ -586,6 +607,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Wmultichar)
Wmultiple-inheritance
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wmultiple-inheritance)
+Wmultiple-parameter-fwd-decl-lists
+UrlSuffix(gcc/Warning-Options.html#index-Wmultiple-parameter-fwd-decl-lists)
+
Wmultistatement-macros
UrlSuffix(gcc/Warning-Options.html#index-Wmultistatement-macros)
@@ -604,6 +628,9 @@ UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-noexcept)
Wnoexcept-type
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-noexcept-type)
+Wnon-c-typedef-for-linkage
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-non-c-typedef-for-linkage)
+
Wnon-template-friend
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-non-template-friend)
@@ -756,6 +783,12 @@ UrlSuffix(gcc/Warning-Options.html#index-Wno-self-move)
Wsequence-point
UrlSuffix(gcc/Warning-Options.html#index-Wno-sequence-point)
+Wsfinae-incomplete=
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-sfinae-incomplete)
+
+Wsfinae-incomplete
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wno-sfinae-incomplete)
+
Wshadow-ivar
UrlSuffix(gcc/Warning-Options.html#index-Wno-shadow-ivar)
@@ -1024,7 +1057,7 @@ UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fassume-sane-operators-new-
; duplicate: 'gdc/Runtime-Options.html#index-fbuiltin'
fcanonical-system-headers
-UrlSuffix(gcc/Preprocessor-Options.html#index-fno-canonical-system-headers)
+UrlSuffix(gcc/Preprocessor-Options.html#index-fcanonical-system-headers)
fchar8_t
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fchar8_005ft)
@@ -1032,6 +1065,9 @@ UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fchar8_005ft)
fconcepts
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fconcepts)
+fconcepts-diagnostics-depth=
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fconcepts-diagnostics-depth)
+
fcond-mismatch
UrlSuffix(gcc/C-Dialect-Options.html#index-fcond-mismatch)
@@ -1074,6 +1110,9 @@ UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fcontract-continuation-mode
fcontract-role=
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fcontract-role)
+fcontract-semantic=
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fcontract-semantic)
+
fcoroutines
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fcoroutines)
@@ -1105,6 +1144,9 @@ UrlSuffix(gcc/Preprocessor-Options.html#index-fmacro-prefix-map)
fdump-ada-spec
UrlSuffix(gcc/Overall-Options.html#index-fdump-ada-spec)
+fdump-ada-spec-slim
+UrlSuffix(gcc/Overall-Options.html#index-fdump-ada-spec-slim)
+
felide-constructors
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-felide-constructors)
diff --git a/gcc/c-family/known-headers.cc b/gcc/c-family/known-headers.cc
index 7e0fa95..e3c0113 100644
--- a/gcc/c-family/known-headers.cc
+++ b/gcc/c-family/known-headers.cc
@@ -329,9 +329,10 @@ suggest_missing_header::~suggest_missing_header ()
/* suggest_missing_option's ctor. */
-suggest_missing_option::suggest_missing_option (location_t loc,
- const char *macro_name,
- diagnostic_option_id option_id)
+suggest_missing_option::
+suggest_missing_option (location_t loc,
+ const char *macro_name,
+ diagnostics::option_id option_id)
: deferred_diagnostic (loc), m_name_str (macro_name), m_option_id (option_id)
{
gcc_assert (macro_name);
diff --git a/gcc/c-family/known-headers.h b/gcc/c-family/known-headers.h
index b1da757..3ffe5f3 100644
--- a/gcc/c-family/known-headers.h
+++ b/gcc/c-family/known-headers.h
@@ -48,12 +48,12 @@ class suggest_missing_option : public deferred_diagnostic
{
public:
suggest_missing_option (location_t loc, const char *name,
- diagnostic_option_id option_id);
+ diagnostics::option_id option_id);
~suggest_missing_option ();
private:
const char *m_name_str;
- diagnostic_option_id m_option_id;
+ diagnostics::option_id m_option_id;
};
#endif /* GCC_KNOWN_HEADERS_H */