aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog385
-rw-r--r--gcc/c-family/c-ada-spec.cc26
-rw-r--r--gcc/c-family/c-attribs.cc232
-rw-r--r--gcc/c-family/c-common.cc143
-rw-r--r--gcc/c-family/c-common.def3
-rw-r--r--gcc/c-family/c-common.h16
-rw-r--r--gcc/c-family/c-cppbuiltin.cc82
-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.cc27
-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.cc313
-rw-r--r--gcc/c-family/c-opts.cc89
-rw-r--r--gcc/c-family/c-pragma.cc19
-rw-r--r--gcc/c-family/c-ubsan.cc321
-rw-r--r--gcc/c-family/c-warn.cc4
-rw-r--r--gcc/c-family/c.opt26
-rw-r--r--gcc/c-family/c.opt.urls18
-rw-r--r--gcc/c-family/known-headers.cc7
-rw-r--r--gcc/c-family/known-headers.h4
21 files changed, 1571 insertions, 195 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 1572c8b..9725521 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,388 @@
+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..1e3a94e 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -489,7 +489,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 },
@@ -1128,11 +1128,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 +1196,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 +1420,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 +1448,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 +1485,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 +1501,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 +1518,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 +2918,53 @@ 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 cannot be applied to a pointer to void type. */
+ else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == VOID_TYPE)
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "%qE attribute is not allowed for a pointer to void",
+ name);
+ *no_add_attrs = true;
+ }
+ /* 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 +2973,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 +4164,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 +5079,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;
@@ -5727,6 +5781,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 +5922,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 +5942,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 +6000,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,7 +6282,9 @@ handle_target_clones_attribute (tree *node, tree name, tree ARG_UNUSED (args),
}
}
- if (get_target_clone_attr_len (args) == -1)
+ auto_vec<string_slice> versions = get_clone_attr_versions (args, NULL);
+
+ if (versions.length () == 1)
{
warning (OPT_Wattributes,
"single %<target_clones%> attribute is ignored");
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 587d764..e7dd460 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. */
@@ -394,6 +395,7 @@ const struct c_common_resword c_common_reswords[] =
{
{ "_Alignas", RID_ALIGNAS, D_CONLY },
{ "_Alignof", RID_ALIGNOF, D_CONLY },
+ { "_Countof", RID_COUNTOF, D_CONLY },
{ "_Atomic", RID_ATOMIC, D_CONLY },
{ "_BitInt", RID_BITINT, D_CONLY },
{ "_Bool", RID_BOOL, D_CONLY },
@@ -3437,20 +3439,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
@@ -4080,6 +4103,31 @@ 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;
+
+ 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;
+ }
+
+ return array_type_nelts_top (type);
+}
/* Handle C and C++ default attributes. */
@@ -5723,8 +5771,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 +5840,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 +5852,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 +6054,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 +6081,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 +6337,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 +7026,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 +7068,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 +7083,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 +9964,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 +10050,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 +10114,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.
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index cf22282..0bcc499 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -50,6 +50,9 @@ 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 '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..b6021d2 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_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,
@@ -746,7 +747,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 +891,7 @@ 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);
/* 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 +979,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 +1265,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 +1303,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 +1347,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;
@@ -1706,7 +1713,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 +1729,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..6b22f9e 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,79 @@ 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_trivial_relocatability=202502L");
+ 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 +1327,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 +1354,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 +1732,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..131eca8 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;
}
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..fe272888 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 "
@@ -4282,6 +4285,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. */
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index 4016382..0ec30e8 100644
--- a/gcc/c-family/c-opts.cc
+++ b/gcc/c-family/c-opts.cc
@@ -32,7 +32,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 +43,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 +169,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 +179,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. */
@@ -278,7 +278,7 @@ c_common_init_options (unsigned int decoded_options_count,
if (c_dialect_cxx ())
set_std_cxx17 (/*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-
@@ -959,6 +959,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 +1094,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 +1119,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 +1174,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 +1200,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 +1227,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)
@@ -2007,8 +2036,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 +2052,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 +2068,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-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-ubsan.cc b/gcc/c-family/c-ubsan.cc
index 78b7868..a64f74e 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;
}
@@ -554,38 +548,317 @@ ubsan_instrument_bounds (location_t loc, tree array, tree *index,
*index, bound);
}
-/* Return true iff T is an array that was instrumented by SANITIZE_BOUNDS. */
+
+/* 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 (array_type), 0);
+ return build_call_expr_internal_loc (loc, IFN_UBSAN_BOUNDS,
+ void_type_node, 3, zero_with_type,
+ *index, bound);
+}
+
+/* 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..09517d2 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -3835,7 +3835,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 +3843,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..3f5e2f0 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -397,6 +397,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 +497,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.
@@ -938,7 +946,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 +964,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.
@@ -1098,6 +1110,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.
@@ -1319,6 +1335,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.
diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls
index ad6d8a0..e09d51d 100644
--- a/gcc/c-family/c.opt.urls
+++ b/gcc/c-family/c.opt.urls
@@ -139,6 +139,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)
@@ -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)
@@ -502,6 +508,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)
@@ -604,6 +613,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 +768,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)
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 */