Message ID | 66b3ff86.a70a0220.1b74f1.01fa@mx.google.com |
---|---|
State | New |
Headers | show |
Series | c++: Add missing auto_diagnostic_groups | expand |
On Thu, Aug 08, 2024 at 09:13:05AM +1000, Nathaniel Shead wrote: > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc > index 6c22ff55b46..03c19e4a7e4 100644 > --- a/gcc/cp/error.cc > +++ b/gcc/cp/error.cc > @@ -4782,12 +4782,14 @@ qualified_name_lookup_error (tree scope, tree name, > scope); > else if (TREE_CODE (decl) == TREE_LIST) > { > + auto_diagnostic_group d; > error_at (location, "reference to %<%T::%D%> is ambiguous", > scope, name); > print_candidates (decl); > } > else > { > + auto_diagnostic_group d; > name_hint hint; > if (SCOPED_ENUM_P (scope) && TREE_CODE (name) == IDENTIFIER_NODE) > hint = suggest_alternative_in_scoped_enum (name, scope); I don't see why we need the second a_d_d here. > @@ -3534,6 +3536,7 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, > else > { > /* Look up the member. */ > + auto_diagnostic_group d; > access_failure_info afi; > if (processing_template_decl) > /* Even though this class member access expression is at this I don't quite see why we need it here, either. > @@ -10384,6 +10401,8 @@ convert_for_assignment (tree type, tree rhs, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > + > /* If the right-hand side has unknown type, then it is an > overloaded function. Call instantiate_type to get error > messages. */ > @@ -10406,7 +10425,6 @@ convert_for_assignment (tree type, tree rhs, > (rhs_loc, > has_loc ? &label : NULL, > has_loc ? highlight_colors::percent_h : NULL); > - auto_diagnostic_group d; Oh I see, it was supposed to be in the outer block. OK. The patch looks good to me, thanks. Marek
On Thu, Aug 08, 2024 at 03:16:24PM -0400, Marek Polacek wrote: > On Thu, Aug 08, 2024 at 09:13:05AM +1000, Nathaniel Shead wrote: > > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc > > index 6c22ff55b46..03c19e4a7e4 100644 > > --- a/gcc/cp/error.cc > > +++ b/gcc/cp/error.cc > > @@ -4782,12 +4782,14 @@ qualified_name_lookup_error (tree scope, tree name, > > scope); > > else if (TREE_CODE (decl) == TREE_LIST) > > { > > + auto_diagnostic_group d; > > error_at (location, "reference to %<%T::%D%> is ambiguous", > > scope, name); > > print_candidates (decl); > > } > > else > > { > > + auto_diagnostic_group d; > > name_hint hint; > > if (SCOPED_ENUM_P (scope) && TREE_CODE (name) == IDENTIFIER_NODE) > > hint = suggest_alternative_in_scoped_enum (name, scope); > > I don't see why we need the second a_d_d here. > The 'suggest_alternative_in_scoped_enum' call can register an 'inform' to be called in 'name_hint's destructor, specifically contained within name_hint::m_deferred (a deferred_diagnostic). Most other uses of 'name_hint' that I could find seemed to be correctly grouped already. > > @@ -3534,6 +3536,7 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, > > else > > { > > /* Look up the member. */ > > + auto_diagnostic_group d; > > access_failure_info afi; > > if (processing_template_decl) > > /* Even though this class member access expression is at this > > I don't quite see why we need it here, either. > A little later on in this block there's afi.maybe_suggest_accessor, which emits an 'inform' with a fixit suggesting how to access the member, which I feel should probably be part of the same group as the error emitted from the 'lookup_member' call. But I suppose this should be grouped more clearly, e.g. --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -3534,7 +3536,6 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, else { /* Look up the member. */ - access_failure_info afi; if (processing_template_decl) /* Even though this class member access expression is at this point not dependent, the member itself may be dependent, and @@ -3543,12 +3544,18 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, ahead of time here; we're going to redo this member lookup at instantiation time anyway. */ push_deferring_access_checks (dk_no_check); - member = lookup_member (access_path, name, /*protect=*/1, - /*want_type=*/false, complain, - &afi); - if (processing_template_decl) - pop_deferring_access_checks (); - afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); + + { + auto_diagnostic_group d; + access_failure_info afi; + member = lookup_member (access_path, name, /*protect=*/1, + /*want_type=*/false, complain, + &afi); + if (processing_template_decl) + pop_deferring_access_checks (); + afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); + } + if (member == NULL_TREE) { if (dependentish_scope_p (object_type)) > > @@ -10384,6 +10401,8 @@ convert_for_assignment (tree type, tree rhs, > > { > > if (complain & tf_error) > > { > > + auto_diagnostic_group d; > > + > > /* If the right-hand side has unknown type, then it is an > > overloaded function. Call instantiate_type to get error > > messages. */ > > @@ -10406,7 +10425,6 @@ convert_for_assignment (tree type, tree rhs, > > (rhs_loc, > > has_loc ? &label : NULL, > > has_loc ? highlight_colors::percent_h : NULL); > > - auto_diagnostic_group d; > > Oh I see, it was supposed to be in the outer block. OK. > > The patch looks good to me, thanks. > > Marek > Thanks, I'll wait for final approval from someone for once I've finished bootstrap+regtest with the above adjustment. Nathaniel
On Fri, Aug 09, 2024 at 11:03:24AM +1000, Nathaniel Shead wrote: > On Thu, Aug 08, 2024 at 03:16:24PM -0400, Marek Polacek wrote: > > On Thu, Aug 08, 2024 at 09:13:05AM +1000, Nathaniel Shead wrote: > > > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc > > > index 6c22ff55b46..03c19e4a7e4 100644 > > > --- a/gcc/cp/error.cc > > > +++ b/gcc/cp/error.cc > > > @@ -4782,12 +4782,14 @@ qualified_name_lookup_error (tree scope, tree name, > > > scope); > > > else if (TREE_CODE (decl) == TREE_LIST) > > > { > > > + auto_diagnostic_group d; > > > error_at (location, "reference to %<%T::%D%> is ambiguous", > > > scope, name); > > > print_candidates (decl); > > > } > > > else > > > { > > > + auto_diagnostic_group d; > > > name_hint hint; > > > if (SCOPED_ENUM_P (scope) && TREE_CODE (name) == IDENTIFIER_NODE) > > > hint = suggest_alternative_in_scoped_enum (name, scope); > > > > I don't see why we need the second a_d_d here. > > > > The 'suggest_alternative_in_scoped_enum' call can register an 'inform' > to be called in 'name_hint's destructor, specifically contained within > name_hint::m_deferred (a deferred_diagnostic). > > Most other uses of 'name_hint' that I could find seemed to be correctly > grouped already. > > > > @@ -3534,6 +3536,7 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, > > > else > > > { > > > /* Look up the member. */ > > > + auto_diagnostic_group d; > > > access_failure_info afi; > > > if (processing_template_decl) > > > /* Even though this class member access expression is at this > > > > I don't quite see why we need it here, either. > > > > A little later on in this block there's afi.maybe_suggest_accessor, > which emits an 'inform' with a fixit suggesting how to access the > member, which I feel should probably be part of the same group as the > error emitted from the 'lookup_member' call. > > But I suppose this should be grouped more clearly, e.g. > > --- a/gcc/cp/typeck.cc > +++ b/gcc/cp/typeck.cc > @@ -3534,7 +3536,6 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, > else > { > /* Look up the member. */ > - access_failure_info afi; > if (processing_template_decl) > /* Even though this class member access expression is at this > point not dependent, the member itself may be dependent, and > @@ -3543,12 +3544,18 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, > ahead of time here; we're going to redo this member lookup at > instantiation time anyway. */ > push_deferring_access_checks (dk_no_check); Actually it feels wrong for the p_d_a_c to not be part of this group; here's a better incremental patch on my first submission: diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index d4fc848bfa1..e4e260645f6 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -3536,22 +3536,24 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, else { /* Look up the member. */ - auto_diagnostic_group d; - access_failure_info afi; - if (processing_template_decl) - /* Even though this class member access expression is at this - point not dependent, the member itself may be dependent, and - we must not potentially push a access check for a dependent - member onto TI_DEFERRED_ACCESS_CHECKS. So don't check access - ahead of time here; we're going to redo this member lookup at - instantiation time anyway. */ - push_deferring_access_checks (dk_no_check); - member = lookup_member (access_path, name, /*protect=*/1, - /*want_type=*/false, complain, - &afi); - if (processing_template_decl) - pop_deferring_access_checks (); - afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); + { + auto_diagnostic_group d; + access_failure_info afi; + if (processing_template_decl) + /* Even though this class member access expression is at this + point not dependent, the member itself may be dependent, and + we must not potentially push a access check for a dependent + member onto TI_DEFERRED_ACCESS_CHECKS. So don't check access + ahead of time here; we're going to redo this member lookup at + instantiation time anyway. */ + push_deferring_access_checks (dk_no_check); + member = lookup_member (access_path, name, /*protect=*/1, + /*want_type=*/false, complain, + &afi); + if (processing_template_decl) + pop_deferring_access_checks (); + afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); + } if (member == NULL_TREE) { if (dependentish_scope_p (object_type)) Nathaniel
On Fri, Aug 09, 2024 at 11:03:24AM +1000, Nathaniel Shead wrote: > On Thu, Aug 08, 2024 at 03:16:24PM -0400, Marek Polacek wrote: > > On Thu, Aug 08, 2024 at 09:13:05AM +1000, Nathaniel Shead wrote: > > > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc > > > index 6c22ff55b46..03c19e4a7e4 100644 > > > --- a/gcc/cp/error.cc > > > +++ b/gcc/cp/error.cc > > > @@ -4782,12 +4782,14 @@ qualified_name_lookup_error (tree scope, tree name, > > > scope); > > > else if (TREE_CODE (decl) == TREE_LIST) > > > { > > > + auto_diagnostic_group d; > > > error_at (location, "reference to %<%T::%D%> is ambiguous", > > > scope, name); > > > print_candidates (decl); > > > } > > > else > > > { > > > + auto_diagnostic_group d; > > > name_hint hint; > > > if (SCOPED_ENUM_P (scope) && TREE_CODE (name) == IDENTIFIER_NODE) > > > hint = suggest_alternative_in_scoped_enum (name, scope); > > > > I don't see why we need the second a_d_d here. > > > > The 'suggest_alternative_in_scoped_enum' call can register an 'inform' > to be called in 'name_hint's destructor, specifically contained within > name_hint::m_deferred (a deferred_diagnostic). > > Most other uses of 'name_hint' that I could find seemed to be correctly > grouped already. Ah okay. > > > @@ -3534,6 +3536,7 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, > > > else > > > { > > > /* Look up the member. */ > > > + auto_diagnostic_group d; > > > access_failure_info afi; > > > if (processing_template_decl) > > > /* Even though this class member access expression is at this > > > > I don't quite see why we need it here, either. > > > > A little later on in this block there's afi.maybe_suggest_accessor, > which emits an 'inform' with a fixit suggesting how to access the > member, which I feel should probably be part of the same group as the > error emitted from the 'lookup_member' call. Interesting. > But I suppose this should be grouped more clearly, e.g. > > --- a/gcc/cp/typeck.cc > +++ b/gcc/cp/typeck.cc > @@ -3534,7 +3536,6 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, > else > { > /* Look up the member. */ > - access_failure_info afi; > if (processing_template_decl) > /* Even though this class member access expression is at this > point not dependent, the member itself may be dependent, and > @@ -3543,12 +3544,18 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, > ahead of time here; we're going to redo this member lookup at > instantiation time anyway. */ > push_deferring_access_checks (dk_no_check); > - member = lookup_member (access_path, name, /*protect=*/1, > - /*want_type=*/false, complain, > - &afi); > - if (processing_template_decl) > - pop_deferring_access_checks (); > - afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); > + > + { > + auto_diagnostic_group d; > + access_failure_info afi; > + member = lookup_member (access_path, name, /*protect=*/1, > + /*want_type=*/false, complain, > + &afi); > + if (processing_template_decl) > + pop_deferring_access_checks (); > + afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); > + } > + > if (member == NULL_TREE) > { > if (dependentish_scope_p (object_type)) > > > > @@ -10384,6 +10401,8 @@ convert_for_assignment (tree type, tree rhs, > > > { > > > if (complain & tf_error) > > > { > > > + auto_diagnostic_group d; > > > + > > > /* If the right-hand side has unknown type, then it is an > > > overloaded function. Call instantiate_type to get error > > > messages. */ > > > @@ -10406,7 +10425,6 @@ convert_for_assignment (tree type, tree rhs, > > > (rhs_loc, > > > has_loc ? &label : NULL, > > > has_loc ? highlight_colors::percent_h : NULL); > > > - auto_diagnostic_group d; > > > > Oh I see, it was supposed to be in the outer block. OK. > > > > The patch looks good to me, thanks. > > > > Marek > > > > Thanks, I'll wait for final approval from someone for once I've finished > bootstrap+regtest with the above adjustment. Nice. Thanks for cleaning this up! Marek
Ping for https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659796.html For clarity's sake, here's the full patch with the adjustment I mentioned earlier: -- >8 -- This patch goes through all .cc files in gcc/cp and adds in any auto_diagnostic_groups that seem to be missing by looking for any 'inform' calls that aren't grouped with their respective error/warning. Now with SARIF output support this seems to be a bit more important. The patch isn't complete; I've tried to also track helper functions used for diagnostics to group them, but some may have been missed. Additionally there are a few functions that are definitely missing groupings but I wasn't able to see an obvious way to add them without potentially grouping together unrelated messages. This list includes: - lazy_load_{binding,pendings} "during load of {binding,pendings} for" - cp_finish_decomp "in initialization of structured binding variable" - require_deduced_type "using __builtin_source_location" - convert_nontype_argument "in template argument for type %qT" - coerce_template_params "so any instantiation with a non-empty parameter pack" - tsubst_default_argument "when instantiating default argument" - invalid_nontype_parm_type_p "invalid template non-type parameter" gcc/cp/ChangeLog: * class.cc (add_method): Add missing auto_diagnostic_group. (handle_using_decl): Likewise. (maybe_warn_about_overly_private_class): Likewise. (check_field_decl): Likewise. (check_field_decls): Likewise. (resolve_address_of_overloaded_function): Likewise. (note_name_declared_in_class): Likewise. * constraint.cc (associate_classtype_constraints): Likewise. (diagnose_trait_expr): Clean up whitespace. * coroutines.cc (find_coro_traits_template_decl): Add missing auto_diagnostic_group. (coro_promise_type_found_p): Likewise. (coro_diagnose_throwing_fn): Likewise. * cvt.cc (build_expr_type_conversion): Likewise. * decl.cc (validate_constexpr_redeclaration): Likewise. (duplicate_function_template_decls): Likewise. (duplicate_decls): Likewise. (lookup_label_1): Likewise. (check_previous_goto_1): Likewise. (check_goto_1): Likewise. (make_typename_type): Likewise. (make_unbound_class_template): Likewise. (check_tag_decl): Likewise. (start_decl): Likewise. (maybe_commonize_var): Likewise. (check_for_uninitialized_const_var): Likewise. (reshape_init_class): Likewise. (check_initializer): Likewise. (cp_finish_decl): Likewise. (find_decomp_class_base): Likewise. (cp_finish_decomp): Likewise. (expand_static_init): Likewise. (grokfndecl): Likewise. (grokdeclarator): Likewise. (check_elaborated_type_specifier): Likewise. (lookup_and_check_tag): Likewise. (xref_tag): Likewise. (cxx_simulate_enum_decl): Likewise. (finish_function): Likewise. * decl2.cc (check_classfn): Likewise. (record_mangling): Likewise. (mark_used): Likewise. * error.cc (qualified_name_lookup_error): Likewise. * except.cc (build_throw): Likewise. * init.cc (get_nsdmi): Likewise. (diagnose_uninitialized_cst_or_ref_member_1): Likewise. (warn_placement_new_too_small): Likewise. (build_new_1): Likewise. (build_vec_delete_1): Likewise. (build_delete): Likewise. * lambda.cc (add_capture): Likewise. (add_default_capture): Likewise. * lex.cc (unqualified_fn_lookup_error): Likewise. * method.cc (synthesize_method): Likewise. (defaulted_late_check): Likewise. * module.cc (trees_in::is_matching_decl): Likewise. (trees_in::read_enum_def): Likewise. (module_state::check_not_purview): Likewise. (module_state::deferred_macro): Likewise. (module_state::read_config): Likewise. (module_state::check_read): Likewise. (declare_module): Likewise. (init_modules): Likewise. * name-lookup.cc (diagnose_name_conflict): Likewise. (lookup_using_decl): Likewise. (set_decl_namespace): Likewise. (finish_using_directive): Likewise. (push_namespace): Likewise. (add_imported_namespace): Likewise. * parser.cc (cp_parser_check_for_definition_in_return_type): Likewise. (cp_parser_userdef_numeric_literal): Likewise. (cp_parser_nested_name_specifier_opt): Likewise. (cp_parser_new_expression): Likewise. (cp_parser_binary_expression): Likewise. (cp_parser_lambda_introducer): Likewise. (cp_parser_module_declaration): Likewise. (cp_parser_import_declaration): Likewise, removing gotos to support this. (cp_parser_declaration): Add missing auto_diagnostic_group. (cp_parser_decl_specifier_seq): Likewise. (cp_parser_template_id): Likewise. (cp_parser_template_name): Likewise. (cp_parser_explicit_specialization): Likewise. (cp_parser_placeholder_type_specifier): Likewise. (cp_parser_elaborated_type_specifier): Likewise. (cp_parser_enum_specifier): Likewise. (cp_parser_asm_definition): Likewise. (cp_parser_init_declarator): Likewise. (cp_parser_direct_declarator): Likewise. (cp_parser_class_head): Likewise. (cp_parser_member_declaration): Likewise. (cp_parser_lookup_name): Likewise. (cp_parser_explicit_template_declaration): Likewise. (cp_parser_check_class_key): Likewise. * pt.cc (maybe_process_partial_specialization): Likewise. (determine_specialization): Likewise. (check_for_bare_parameter_packs): Likewise. (check_template_shadow): Likewise. (process_partial_specialization): Likewise. (push_template_decl): Likewise. (redeclare_class_template): Likewise. (convert_nontype_argument_function): Likewise. (check_valid_ptrmem_cst_expr): Likewise. (convert_nontype_argument): Likewise. (convert_template_argument): Likewise. (coerce_template_parms): Likewise. (tsubst_qualified_id): Likewise. (tsubst_expr): Likewise. (most_specialized_partial_spec): Likewise. (do_class_deduction): Likewise. (do_auto_deduction): Likewise. * search.cc (lookup_member): Likewise. * semantics.cc (finish_non_static_data_member): Likewise. (process_outer_var_ref): Likewise. (finish_id_expression_1): Likewise. (finish_offsetof): Likewise. (omp_reduction_lookup): Likewise. (finish_omp_clauses): Likewise. * tree.cc (check_abi_tag_redeclaration): Likewise. (check_abi_tag_args): Likewise. * typeck.cc (invalid_nonstatic_memfn_p): Likewise. (complain_about_unrecognized_member): Likewise. (finish_class_member_access_expr): Likewise. (error_args_num): Likewise. (warn_for_null_address): Likewise. (cp_build_binary_op): Likewise. (build_x_unary_op): Likewise. (cp_build_unary_op): Likewise. (build_static_cast): Likewise. (cp_build_modify_expr): Likewise. (get_delta_difference): Likewise. (convert_for_assignment): Widen scope of auto_diagnostic_group. (check_return_expr): Add missing auto_diagnostic_group. * typeck2.cc (cxx_incomplete_type_diagnostic): Likewise. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Marek Polacek <polacek@redhat.com> --- gcc/cp/class.cc | 12 +++++ gcc/cp/constraint.cc | 21 +++++---- gcc/cp/coroutines.cc | 3 ++ gcc/cp/cvt.cc | 1 + gcc/cp/decl.cc | 59 +++++++++++++++++++++-- gcc/cp/decl2.cc | 3 ++ gcc/cp/error.cc | 2 + gcc/cp/except.cc | 1 + gcc/cp/init.cc | 8 ++++ gcc/cp/lambda.cc | 3 ++ gcc/cp/lex.cc | 1 + gcc/cp/method.cc | 3 ++ gcc/cp/module.cc | 8 ++++ gcc/cp/name-lookup.cc | 7 +++ gcc/cp/parser.cc | 107 ++++++++++++++++++++++++++++-------------- gcc/cp/pt.cc | 65 ++++++++++++++++++------- gcc/cp/search.cc | 1 + gcc/cp/semantics.cc | 9 ++++ gcc/cp/tree.cc | 3 ++ gcc/cp/typeck.cc | 79 +++++++++++++++++++------------ gcc/cp/typeck2.cc | 1 + 21 files changed, 303 insertions(+), 94 deletions(-) diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index fb6c3370950..950d83b0ea4 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -1431,6 +1431,7 @@ add_method (tree type, tree method, bool via_using) continue; } + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (method), "%q#D conflicts with version inherited from %qT", method, basef); @@ -1453,6 +1454,7 @@ add_method (tree type, tree method, bool via_using) } else { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (method), "%q#D cannot be overloaded with %q#D", method, fn); inform (DECL_SOURCE_LOCATION (fn), @@ -1604,6 +1606,7 @@ handle_using_decl (tree using_decl, tree t) ; else if (is_overloaded_fn (old_value)) { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T " "because of local method %q#D with same name", using_decl, t, old_value); @@ -1613,6 +1616,7 @@ handle_using_decl (tree using_decl, tree t) } else if (!DECL_ARTIFICIAL (old_value)) { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T " "because of local member %q#D with same name", using_decl, t, old_value); @@ -2547,6 +2551,7 @@ maybe_warn_about_overly_private_class (tree t) if (!nonprivate_ctor) { + auto_diagnostic_group d; bool w = warning (OPT_Wctor_dtor_privacy, "%q#T only defines private constructors and has " "no friends", t); @@ -3815,6 +3820,7 @@ check_field_decl (tree field, if (TREE_CODE (t) == UNION_TYPE && cxx_dialect < cxx11) { static bool warned; + auto_diagnostic_group d; int oldcount = errorcount; if (TYPE_NEEDS_CONSTRUCTING (type)) error ("member %q+#D with constructor not allowed in union", @@ -4131,6 +4137,7 @@ check_field_decls (tree t, tree *access_decls, if (default_init_member && TREE_CODE (t) == UNION_TYPE) { + auto_diagnostic_group d; error ("multiple fields in union %qT initialized", t); inform (DECL_SOURCE_LOCATION (default_init_member), "initialized member %q+D declared here", @@ -4209,6 +4216,7 @@ check_field_decls (tree t, tree *access_decls, && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) && !(TYPE_HAS_COPY_CTOR (t) && TYPE_HAS_COPY_ASSIGN (t))) { + auto_diagnostic_group d; if (warning (OPT_Weffc__, "%q#T has pointer data members", t)) { if (! TYPE_HAS_COPY_CTOR (t)) @@ -8913,6 +8921,7 @@ resolve_address_of_overloaded_function (tree target_type, /* There were *no* matches. */ if (complain & tf_error) { + auto_diagnostic_group d; error ("no matches converting function %qD to type %q#T", OVL_NAME (overload), target_type); @@ -8940,6 +8949,7 @@ resolve_address_of_overloaded_function (tree target_type, { if (complain & tf_error) { + auto_diagnostic_group d; error ("converting overloaded function %qD to type %q#T is ambiguous", OVL_NAME (overload), target_type); @@ -9397,6 +9407,8 @@ note_name_declared_in_class (tree name, tree decl) else /* Make it an error. */ global_dc->m_pedantic_errors = 1; + + auto_diagnostic_group d; if (pedwarn (location_of (decl), OPT_Wchanges_meaning, "declaration of %q#D changes meaning of %qD", decl, OVL_NAME (decl))) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index f79407f2cdb..ebfcdefd284 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -1005,6 +1005,7 @@ associate_classtype_constraints (tree type) } if (!equivalent_constraints (ci, orig_ci)) { + auto_diagnostic_group d; error ("%qT does not match original declaration", type); tree tmpl = CLASSTYPE_TI_TEMPLATE (type); location_t loc = DECL_SOURCE_LOCATION (tmpl); @@ -3183,9 +3184,9 @@ diagnose_trait_expr (tree expr, tree args) break; case CPTK_IS_CONSTRUCTIBLE: if (!t2) - inform (loc, " %qT is not default constructible", t1); + inform (loc, " %qT is not default constructible", t1); else - inform (loc, " %qT is not constructible from %qE", t1, t2); + inform (loc, " %qT is not constructible from %qE", t1, t2); break; case CPTK_IS_CONVERTIBLE: inform (loc, " %qT is not convertible from %qE", t2, t1); @@ -3204,9 +3205,9 @@ diagnose_trait_expr (tree expr, tree args) break; case CPTK_IS_INVOCABLE: if (!t2) - inform (loc, " %qT is not invocable", t1); + inform (loc, " %qT is not invocable", t1); else - inform (loc, " %qT is not invocable by %qE", t1, t2); + inform (loc, " %qT is not invocable by %qE", t1, t2); break; case CPTK_IS_LAYOUT_COMPATIBLE: inform (loc, " %qT is not layout compatible with %qT", t1, t2); @@ -3233,14 +3234,14 @@ diagnose_trait_expr (tree expr, tree args) inform (loc, " %qT is not nothrow constructible from %qE", t1, t2); break; case CPTK_IS_NOTHROW_CONVERTIBLE: - inform (loc, " %qT is not nothrow convertible from %qE", t2, t1); + inform (loc, " %qT is not nothrow convertible from %qE", t2, t1); break; case CPTK_IS_NOTHROW_INVOCABLE: - if (!t2) - inform (loc, " %qT is not nothrow invocable", t1); - else - inform (loc, " %qT is not nothrow invocable by %qE", t1, t2); - break; + if (!t2) + inform (loc, " %qT is not nothrow invocable", t1); + else + inform (loc, " %qT is not nothrow invocable by %qE", t1, t2); + break; case CPTK_IS_OBJECT: inform (loc, " %qT is not an object type", t1); break; diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 20bda5520c0..e605eaec7a4 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -305,6 +305,7 @@ find_coro_traits_template_decl (location_t kw) { if (!traits_error_emitted) { + auto_diagnostic_group d; gcc_rich_location richloc (kw); error_at (&richloc, "coroutines require a traits template; cannot" " find %<%E::%E%>", std_node, coro_traits_identifier); @@ -632,6 +633,7 @@ coro_promise_type_found_p (tree fndecl, location_t loc) tf_none); if (has_ret_void && has_ret_val) { + auto_diagnostic_group d; location_t ploc = DECL_SOURCE_LOCATION (fndecl); if (!coro_info->coro_co_return_error_emitted) error_at (ploc, "the coroutine promise type %qT declares both" @@ -1025,6 +1027,7 @@ coro_diagnose_throwing_fn (tree fndecl) { if (!TYPE_NOTHROW_P (TREE_TYPE (fndecl))) { + auto_diagnostic_group d; location_t f_loc = cp_expr_loc_or_loc (fndecl, DECL_SOURCE_LOCATION (fndecl)); error_at (f_loc, "the expression %qE is required to be non-throwing", diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc index 7b4bd8a9dc4..df02b8faaf5 100644 --- a/gcc/cp/cvt.cc +++ b/gcc/cp/cvt.cc @@ -1933,6 +1933,7 @@ build_expr_type_conversion (int desires, tree expr, bool complain) { if (complain) { + auto_diagnostic_group d; error ("ambiguous default type conversion from %qT", basetype); inform (input_location, diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 6458e96bded..7bad3047ad9 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -1457,6 +1457,7 @@ validate_constexpr_redeclaration (tree old_decl, tree new_decl) if (DECL_IMMEDIATE_FUNCTION_P (old_decl) || DECL_IMMEDIATE_FUNCTION_P (new_decl)) kind = "consteval"; + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (new_decl), "redeclaration %qD differs in %qs " "from previous declaration", new_decl, @@ -1567,6 +1568,7 @@ duplicate_function_template_decls (tree newdecl, tree olddecl) if (template_heads_equivalent_p (newdecl, olddecl) && function_requirements_equivalent_p (newres, oldres)) { + auto_diagnostic_group d; error ("ambiguating new declaration %q+#D", newdecl); inform (DECL_SOURCE_LOCATION (olddecl), "old declaration %q#D", olddecl); @@ -1902,6 +1904,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) return NULL_TREE; /* There can only be one! */ + auto_diagnostic_group d; if (TREE_CODE (newdecl) == TEMPLATE_DECL && check_raw_literal_operator (olddecl)) error_at (newdecl_loc, @@ -1924,6 +1927,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) /* One is an implicit typedef, that's ok. */ return NULL_TREE; + auto_diagnostic_group d; error ("%q#D redeclared as different kind of entity", newdecl); inform (olddecl_loc, "previous declaration %q#D", olddecl); @@ -1947,6 +1951,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) if (TREE_CODE (oldres) == TYPE_DECL || TREE_CODE (newres) == TYPE_DECL) { + auto_diagnostic_group d; error_at (newdecl_loc, "conflicting declaration of template %q#D", newdecl); inform (olddecl_loc, @@ -1967,6 +1972,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) { if (DECL_EXTERN_C_P (newdecl) && DECL_EXTERN_C_P (olddecl)) { + auto_diagnostic_group d; error_at (newdecl_loc, "conflicting declaration of C function %q#D", newdecl); @@ -1988,6 +1994,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) // And the same constraints. && equivalently_constrained (newdecl, olddecl)) { + auto_diagnostic_group d; error_at (newdecl_loc, "ambiguating new declaration of %q#D", newdecl); inform (olddecl_loc, @@ -1999,6 +2006,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) } else { + auto_diagnostic_group d; error_at (newdecl_loc, "conflicting declaration %q#D", newdecl); inform (olddecl_loc, "previous declaration as %q#D", olddecl); @@ -2010,6 +2018,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) { /* OMP UDRs are never duplicates. */ gcc_assert (DECL_OMP_DECLARE_REDUCTION_P (olddecl)); + auto_diagnostic_group d; error_at (newdecl_loc, "redeclaration of %<pragma omp declare reduction%>"); inform (olddecl_loc, @@ -2311,10 +2320,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) { if (merge_attr) { - if (diagnose_mismatched_attributes (olddecl, newdecl)) - inform (olddecl_loc, DECL_INITIAL (olddecl) - ? G_("previous definition of %qD here") - : G_("previous declaration of %qD here"), olddecl); + { + auto_diagnostic_group d; + if (diagnose_mismatched_attributes (olddecl, newdecl)) + inform (olddecl_loc, DECL_INITIAL (olddecl) + ? G_("previous definition of %qD here") + : G_("previous declaration of %qD here"), olddecl); + } /* [dcl.attr.noreturn]: The first declaration of a function shall specify the noreturn attribute if any declaration of that function @@ -2327,6 +2339,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) && cxx11_attribute_p (a) && get_attribute_namespace (a) == NULL_TREE) { + auto_diagnostic_group d; error_at (newdecl_loc, "function %qD declared %<[[noreturn]]%> " "but its first declaration was not", newdecl); inform (olddecl_loc, "previous declaration of %qD", olddecl); @@ -3597,6 +3610,7 @@ lookup_label_1 (tree id, bool making_local_p) if (old->binding_level == current_binding_level) { + auto_diagnostic_group d; error ("local label %qE conflicts with existing label", id); inform (DECL_SOURCE_LOCATION (old->label_decl), "previous label"); return NULL; @@ -3712,6 +3726,7 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, bool exited_omp, const location_t *locus, vec<tree,va_gc> *computed) { + auto_diagnostic_group d; cp_binding_level *b; bool complained = false; int identified = 0; @@ -3858,6 +3873,7 @@ check_switch_goto (cp_binding_level* level) void check_goto_1 (named_label_entry *ent, bool computed) { + auto_diagnostic_group d; tree decl = ent->label_decl; /* If the label hasn't been defined yet, defer checking. */ @@ -4531,6 +4547,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, { if (complain & tf_error) { + auto_diagnostic_group d; error ("lookup of %qT in %qT is ambiguous", name, context); print_candidates (t); } @@ -4626,6 +4643,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list, { if (complain & tf_error) { + auto_diagnostic_group d; error ("template parameters do not match template %qD", tmpl); inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here", tmpl); @@ -5764,6 +5782,7 @@ check_tag_decl (cp_decl_specifier_seq *declspecs, No attribute-specifier-seq shall appertain to an explicit instantiation. */ { + auto_diagnostic_group d; if (warning_at (loc, OPT_Wattributes, "attribute ignored in explicit instantiation %q#T", declared_type)) @@ -5999,6 +6018,7 @@ start_decl (const cp_declarator *declarator, /* OK, specialization was already checked. */; else if (variable_template_p (field) && !this_tmpl) { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (decl), "non-member-template declaration of %qD", decl); inform (DECL_SOURCE_LOCATION (field), "does not match " @@ -6661,6 +6681,7 @@ maybe_commonize_var (tree decl) msg = G_("sorry: semantics of inline function " "static data %q#D are wrong (you%'ll wind " "up with multiple copies)"); + auto_diagnostic_group d; if (warning_at (DECL_SOURCE_LOCATION (decl), 0, msg, decl)) inform (DECL_SOURCE_LOCATION (decl), @@ -6698,6 +6719,7 @@ check_for_uninitialized_const_var (tree decl, bool constexpr_context_p, if (!field) return true; + auto_diagnostic_group d; bool show_notes = true; if (!constexpr_context_p || cxx_dialect >= cxx20) @@ -7062,6 +7084,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p, { if (field && TREE_CODE (field) == TREE_LIST) { + auto_diagnostic_group g; error ("request for member %qD is ambiguous", d->cur->index); print_candidates (field); @@ -7884,6 +7907,7 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups) { static int explained = 0; + auto_diagnostic_group d; if (cxx_dialect < cxx11) error ("initializer invalid for static member with constructor"); else if (cxx_dialect < cxx17) @@ -8560,6 +8584,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, && !type_uses_auto (type) && !COMPLETE_TYPE_P (complete_type (type))) { + auto_diagnostic_group d; error_at (location_of (decl), "deduced type %qT for %qD is incomplete", type, decl); cxx_incomplete_type_inform (type); @@ -9059,6 +9084,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, complete_type (TREE_TYPE (decl)); if (!omp_mappable_type (TREE_TYPE (decl))) { + auto_diagnostic_group d; error ("%q+D in declare target directive does not have mappable" " type", decl); if (TREE_TYPE (decl) != error_mark_node @@ -9114,6 +9140,7 @@ find_decomp_class_base (location_t loc, tree type, tree ret) return type; else if (ANON_AGGR_TYPE_P (TREE_TYPE (field))) { + auto_diagnostic_group d; if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE) error_at (loc, "cannot decompose class type %qT because it has an " "anonymous struct member", type); @@ -9125,6 +9152,7 @@ find_decomp_class_base (location_t loc, tree type, tree ret) } else if (!accessible_p (type, field, true)) { + auto_diagnostic_group d; error_at (loc, "cannot decompose inaccessible member %qD of %qT", field, type); inform (DECL_SOURCE_LOCATION (field), @@ -9425,6 +9453,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp) if (count != eltscnt) { cnt_mismatch: + auto_diagnostic_group d; if (count > eltscnt) error_n (loc, count, "%u name provided for structured binding", @@ -9505,6 +9534,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp) } if (!tree_fits_uhwi_p (tsize)) { + auto_diagnostic_group d; error_n (loc, count, "%u name provided for structured binding", "%u names provided for structured binding", count); @@ -10096,6 +10126,7 @@ expand_static_init (tree decl, tree init) if (CP_DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl) && !DECL_FUNCTION_SCOPE_P (decl)) { + auto_diagnostic_group d; location_t dloc = DECL_SOURCE_LOCATION (decl); if (init) error_at (dloc, "non-local variable %qD declared %<__thread%> " @@ -10870,6 +10901,7 @@ grokfndecl (tree ctype, if (in_namespace == NULL_TREE && CP_DECL_CONTEXT (decl) != CP_TYPE_CONTEXT (type)) { + auto_diagnostic_group d; error_at (location, "deduction guide %qD must be declared in the " "same scope as %qT", decl, type); inform (location_of (type), " declared here"); @@ -10878,6 +10910,7 @@ grokfndecl (tree ctype, if (DECL_CLASS_SCOPE_P (decl) && current_access_specifier != declared_access (TYPE_NAME (type))) { + auto_diagnostic_group d; error_at (location, "deduction guide %qD must have the same access " "as %qT", decl, type); inform (location_of (type), " declared here"); @@ -10897,6 +10930,7 @@ grokfndecl (tree ctype, /* [over.literal]/6: Literal operators shall not have C linkage. */ if (DECL_LANGUAGE (decl) == lang_c) { + auto_diagnostic_group d; error_at (location, "literal operator with C linkage"); maybe_show_extern_c_location (); return NULL_TREE; @@ -11063,6 +11097,7 @@ grokfndecl (tree ctype, } else if (DECL_DEFAULTED_FN (old_decl)) { + auto_diagnostic_group d; error ("definition of explicitly-defaulted %q+D", decl); inform (DECL_SOURCE_LOCATION (old_decl), "%q#D explicitly defaulted here", old_decl); @@ -13219,6 +13254,7 @@ grokdeclarator (const cp_declarator *declarator, && !diagnose_misapplied_contracts (declspecs->std_attributes)) { location_t attr_loc = declspecs->locations[ds_std_attribute]; + auto_diagnostic_group d; if (any_nonignored_attribute_p (declspecs->std_attributes) && warning_at (attr_loc, OPT_Wattributes, "attribute ignored")) inform (attr_loc, "an attribute that appertains to a type-specifier " @@ -13290,6 +13326,7 @@ grokdeclarator (const cp_declarator *declarator, && (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ENUMERAL_TYPE))) { + auto_diagnostic_group d; if (warning_at (declarator->parenthesized, OPT_Wparentheses, "unnecessary parentheses in declaration of %qs", name)) @@ -13450,6 +13487,7 @@ grokdeclarator (const cp_declarator *declarator, /* OK for C++11 lambdas. */; else if (cxx_dialect < cxx14) { + auto_diagnostic_group d; error_at (typespec_loc, "%qs function uses " "%<auto%> type specifier without " "trailing return type", name); @@ -13501,6 +13539,7 @@ grokdeclarator (const cp_declarator *declarator, } else if (!late_return_type) { + auto_diagnostic_group d; error_at (declarator->id_loc, "deduction guide " "for %qT must have trailing return " "type", TREE_TYPE (tmpl)); @@ -14737,6 +14776,7 @@ grokdeclarator (const cp_declarator *declarator, tree tmpl = TREE_OPERAND (unqualified_id, 0); if (variable_template_p (tmpl)) { + auto_diagnostic_group d; error_at (id_loc, "specialization of variable template " "%qD declared as function", tmpl); inform (DECL_SOURCE_LOCATION (tmpl), @@ -14803,6 +14843,7 @@ grokdeclarator (const cp_declarator *declarator, { if (unqualified_id) { + auto_diagnostic_group d; error_at (id_loc, "field %qD has incomplete type %qT", unqualified_id, type); cxx_incomplete_type_inform (strip_array_types (type)); @@ -14848,6 +14889,7 @@ grokdeclarator (const cp_declarator *declarator, && !all_attributes_are_contracts_p (*attrlist)) { *attrlist = NULL_TREE; + auto_diagnostic_group d; if (warning_at (id_loc, OPT_Wattributes, "attribute ignored")) inform (id_loc, "an attribute that appertains to a friend " "declaration that is not a definition is ignored"); @@ -16359,6 +16401,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, && !DECL_SELF_REFERENCE_P (decl) && tag_code != typename_type) { + auto_diagnostic_group d; if (alias_template_specialization_p (type, nt_opaque)) error ("using alias template specialization %qT after %qs", type, tag_name (tag_code)); @@ -16373,6 +16416,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, && tag_code != enum_type && tag_code != typename_type) { + auto_diagnostic_group d; error ("%qT referred to as %qs", type, tag_name (tag_code)); inform (location_of (type), "%qT has a previous declaration here", type); return error_mark_node; @@ -16380,6 +16424,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, else if (TREE_CODE (type) != ENUMERAL_TYPE && tag_code == enum_type) { + auto_diagnostic_group d; error ("%qT referred to as enum", type); inform (location_of (type), "%qT has a previous declaration here", type); return error_mark_node; @@ -16437,6 +16482,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, if (TREE_CODE (decl) == TREE_LIST) { + auto_diagnostic_group d; error ("reference to %qD is ambiguous", name); print_candidates (decl); return error_mark_node; @@ -16446,6 +16492,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, && !template_header_p && how == TAG_how::CURRENT_ONLY) { + auto_diagnostic_group d; error ("class template %qD redeclared as non-template", name); inform (location_of (decl), "previous declaration here"); CLASSTYPE_ERRONEOUS (TREE_TYPE (decl)) = true; @@ -16496,6 +16543,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, && (!CLASSTYPE_TEMPLATE_INFO (t) || (!PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))))) { + auto_diagnostic_group d; error ("%qT is not a template", t); inform (location_of (t), "previous declaration here"); if (TYPE_CLASS_SCOPE_P (t) @@ -16632,6 +16680,7 @@ xref_tag (enum tag_types tag_code, tree name, && CLASS_TYPE_P (t) && CLASSTYPE_IS_TEMPLATE (t)) { + auto_diagnostic_group d; error ("redeclaration of %qT as a non-template", t); inform (location_of (t), "previous declaration %qD", t); return error_mark_node; @@ -17623,6 +17672,7 @@ cxx_simulate_enum_decl (location_t loc, const char *name, NULL_TREE, false, NULL); if (!OPAQUE_ENUM_P (enumtype)) { + auto_diagnostic_group d; error_at (loc, "multiple definition of %q#T", enumtype); inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)), "previous definition here"); @@ -18679,6 +18729,7 @@ finish_function (bool inline_p) else if (!current_function_returns_value && !current_function_returns_null) { + auto_diagnostic_group d; error ("no return statements in function returning %qT", DECL_SAVED_AUTO_RETURN_TYPE (fndecl)); inform (input_location, "only plain %<auto%> return type can be " diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index c67e3e0c15f..3c4f34868ee 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -911,6 +911,7 @@ check_classfn (tree ctype, tree function, tree template_parms) if (DECL_CONV_FN_P (function)) fns = get_class_binding (ctype, conv_op_identifier); + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (function), "no declaration matches %q#D", function); if (fns) @@ -5120,6 +5121,7 @@ record_mangling (tree decl, bool need_warning) *slot = decl; else if (need_warning) { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (decl), "mangling of %q#D as %qE conflicts with a previous mangle", decl, id); @@ -6078,6 +6080,7 @@ mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */) sorry ("converting lambda that uses %<...%> to function pointer"); else if (complain & tf_error) { + auto_diagnostic_group d; if (DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST) { diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index 420fad26b7b..60d1e8bdb32 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -4796,12 +4796,14 @@ qualified_name_lookup_error (tree scope, tree name, scope); else if (TREE_CODE (decl) == TREE_LIST) { + auto_diagnostic_group d; error_at (location, "reference to %<%T::%D%> is ambiguous", scope, name); print_candidates (decl); } else { + auto_diagnostic_group d; name_hint hint; if (SCOPED_ENUM_P (scope) && TREE_CODE (name) == IDENTIFIER_NODE) hint = suggest_alternative_in_scoped_enum (name, scope); diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc index 0231bd2507d..7b4abd1f56e 100644 --- a/gcc/cp/except.cc +++ b/gcc/cp/except.cc @@ -736,6 +736,7 @@ build_throw (location_t loc, tree exp, tsubst_flags_t complain) exp = moved; /* Call the copy constructor. */ + auto_diagnostic_group d; releasing_vec exp_vec (make_tree_vector_single (exp)); exp = build_special_member_call (object, complete_ctor_identifier, &exp_vec, TREE_TYPE (object), flags, diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index 20373d26988..be7fdb40dd6 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -662,6 +662,7 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain) { if (complain & tf_error) { + auto_diagnostic_group d; error ("default member initializer for %qD required before the end " "of its enclosing class", member); inform (location_of (init), "defined here"); @@ -2736,6 +2737,7 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, ++ error_count; if (complain) { + auto_diagnostic_group d; if (DECL_CONTEXT (field) == origin) { if (using_new) @@ -2764,6 +2766,7 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, ++ error_count; if (complain) { + auto_diagnostic_group d; if (DECL_CONTEXT (field) == origin) { if (using_new) @@ -2890,6 +2893,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper) bool warned = false; if (nelts) nelts = fold_for_warn (nelts); + + auto_diagnostic_group d; if (nelts) if (CONSTANT_CLASS_P (nelts)) warned = warning_at (loc, OPT_Wplacement_new_, @@ -3408,6 +3413,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, { if (complain & tf_error) { + auto_diagnostic_group d; error ("request for member %qD is ambiguous", fnname); print_candidates (fns); } @@ -4125,6 +4131,7 @@ build_vec_delete_1 (location_t loc, tree base, tree maxindex, tree type, { if (complain & tf_error) { + auto_diagnostic_group d; int saved_errorcount = errorcount; if (permerror_opt (loc, OPT_Wdelete_incomplete, "operator %<delete []%> used on " @@ -5209,6 +5216,7 @@ build_delete (location_t loc, tree otype, tree addr, { if (complain & tf_error) { + auto_diagnostic_group d; int saved_errorcount = errorcount; if (permerror_opt (loc, OPT_Wdelete_incomplete, "operator %<delete%> used on " diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index 0770417810e..e17c00217b2 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -562,6 +562,7 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, else if (!dependent_type_p (type) && variably_modified_type_p (type, NULL_TREE)) { + auto_diagnostic_group d; sorry ("capture of variably-modified type %qT that is not an N3639 array " "of runtime bound", type); if (TREE_CODE (type) == ARRAY_TYPE @@ -600,6 +601,7 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, type = complete_type (type); if (!COMPLETE_TYPE_P (type)) { + auto_diagnostic_group d; error ("capture by copy of incomplete type %qT", type); cxx_incomplete_type_inform (type); return error_mark_node; @@ -757,6 +759,7 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) && this_capture_p && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_COPY) { + auto_diagnostic_group d; if (warning_at (LAMBDA_EXPR_LOCATION (lambda), OPT_Wdeprecated, "implicit capture of %qE via %<[=]%> is deprecated " "in C++20", this_identifier)) diff --git a/gcc/cp/lex.cc b/gcc/cp/lex.cc index 1110db7f8d0..79d9490c4ad 100644 --- a/gcc/cp/lex.cc +++ b/gcc/cp/lex.cc @@ -807,6 +807,7 @@ unqualified_fn_lookup_error (cp_expr name_expr) Note that we have the exact wording of the following message in the manual (trouble.texi, node "Name lookup"), so they need to be kept in synch. */ + auto_diagnostic_group d; permerror (loc, "there are no arguments to %qD that depend on a template " "parameter, so a declaration of %qD must be available", name, name); diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index 0b21656ed61..68a776d2c5a 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -1787,6 +1787,7 @@ synthesize_method (tree fndecl) int error_count = errorcount; int warning_count = warningcount + werrorcount; special_function_kind sfk = special_function_p (fndecl); + auto_diagnostic_group d; /* Reset the source location, we might have been previously deferred, and thus have saved where we were first needed. */ @@ -3558,6 +3559,7 @@ defaulted_late_check (tree fn) TREE_TYPE (TREE_TYPE (implicit_fn))) || !compare_fn_params (fn, implicit_fn)) { + auto_diagnostic_group d; error ("defaulted declaration %q+D does not match the " "expected signature", fn); inform (DECL_SOURCE_LOCATION (fn), @@ -3593,6 +3595,7 @@ defaulted_late_check (tree fn) { if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) { + auto_diagnostic_group d; error ("explicitly defaulted function %q+D cannot be declared " "%qs because the implicit declaration is not %qs:", fn, DECL_IMMEDIATE_FUNCTION_P (fn) ? "consteval" : "constexpr", diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 95c2405fcd4..647208944da 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -11627,6 +11627,7 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef) { // FIXME:QOI Might be template specialization from a module, // not necessarily global module + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (decl), "conflicting global module declaration %#qD", decl); inform (DECL_SOURCE_LOCATION (existing), @@ -12682,6 +12683,7 @@ trees_in::read_enum_def (tree defn, tree maybe_template) if (known || values) { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (maybe_dup), "definition of %qD does not match", maybe_dup); inform (DECL_SOURCE_LOCATION (defn), @@ -14497,6 +14499,7 @@ module_state::check_not_purview (location_t from) if (imp == this) { /* Cannot import the current module. */ + auto_diagnostic_group d; error_at (from, "cannot import module in its own purview"); inform (loc, "module %qs declared here", get_flatname ()); return false; @@ -17859,6 +17862,7 @@ module_state::deferred_macro (cpp_reader *reader, location_t loc, { /* If LOC is the first loc, this is the end of file check, which is a warning. */ + auto_diagnostic_group d; if (loc == MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (line_table, 0))) warning_at (loc, OPT_Winvalid_imported_macros, "inconsistent imported macro definition %qE", @@ -18133,6 +18137,7 @@ module_state::read_config (module_state_config &config) /* Reject when either is non-experimental or when experimental major versions differ. */ + auto_diagnostic_group d; bool reject_p = ((!IS_EXPERIMENTAL (my_ver) || !IS_EXPERIMENTAL (their_ver) || MODULE_MAJOR (my_ver) != MODULE_MAJOR (their_ver)) @@ -18945,6 +18950,7 @@ module_state::check_read (bool outermost, bool ok) if (int e = from ()->get_error ()) { + auto_diagnostic_group d; error_at (loc, "failed to read compiled module: %s", from ()->get_error (filename)); note_cmi_name (); @@ -19878,6 +19884,7 @@ declare_module (module_state *module, location_t from_loc, bool exporting_p, module_state *current = (*modules)[0]; if (module_purview_p () || module->loadedness > ML_CONFIG) { + auto_diagnostic_group d; error_at (from_loc, module_purview_p () ? G_("module already declared") : G_("module already imported")); @@ -20535,6 +20542,7 @@ init_modules (cpp_reader *reader) || (cpp_opts->deps.style != DEPS_NONE && !cpp_opts->deps.need_preprocessor_output)) { + auto_diagnostic_group d; warning (0, flag_dump_macros == 'M' ? G_("macro debug output may be incomplete with modules") : G_("module dependencies require preprocessing")); diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 70ad4cbf3b5..7a6cc244c15 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -2893,6 +2893,7 @@ supplement_binding (cxx_binding *binding, tree decl) void diagnose_name_conflict (tree decl, tree bval) { + auto_diagnostic_group d; if (TREE_CODE (decl) == TREE_CODE (bval) && TREE_CODE (decl) != NAMESPACE_DECL && !DECL_DECLARES_FUNCTION_P (decl) @@ -6213,6 +6214,7 @@ lookup_using_decl (tree scope, name_lookup &lookup) /* We can (independently) have ambiguous implicit typedefs. */ || (lookup.type && TREE_CODE (lookup.type) == TREE_LIST)) { + auto_diagnostic_group d; error ("reference to %qD is ambiguous", lookup.name); print_candidates (TREE_CODE (lookup.value) == TREE_LIST ? lookup.value : lookup.type); @@ -6344,6 +6346,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp) if (TREE_CODE (old) == TREE_LIST) { ambiguous: + auto_diagnostic_group d; DECL_CONTEXT (decl) = FROB_CONTEXT (scope); error ("reference to %qD is ambiguous", decl); print_candidates (old); @@ -6443,6 +6446,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp) { if (hidden_p) { + auto_diagnostic_group d; pedwarn (DECL_SOURCE_LOCATION (decl), 0, "%qD has not been declared within %qD", decl, scope); inform (DECL_SOURCE_LOCATION (found), @@ -8927,6 +8931,7 @@ finish_using_directive (tree target, tree attribs) if (current_binding_level->kind == sk_namespace && is_attribute_p ("strong", name)) { + auto_diagnostic_group d; if (warning (0, "%<strong%> using directive no longer supported") && CP_DECL_CONTEXT (target) == current_namespace) inform (DECL_SOURCE_LOCATION (target), @@ -9246,6 +9251,7 @@ push_namespace (tree name, bool make_inline) if (make_inline && !DECL_NAMESPACE_INLINE_P (ns)) { + auto_diagnostic_group d; error_at (input_location, "inline namespace must be specified at initial definition"); inform (DECL_SOURCE_LOCATION (ns), "%qD defined here", ns); @@ -9296,6 +9302,7 @@ add_imported_namespace (tree ctx, tree name, location_t loc, unsigned import, } else if (DECL_NAMESPACE_INLINE_P (decl) != inline_p) { + auto_diagnostic_group d; error_at (loc, "%s namespace %qD conflicts with reachable definition", inline_p ? "inline" : "non-inline", decl); inform (DECL_SOURCE_LOCATION (decl), "reachable %s definition here", diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index edfa5a49440..8391ce431f3 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -3504,6 +3504,7 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator, if (declarator && declarator->kind == cdk_function) { + auto_diagnostic_group d; error_at (type_location, "new types may not be defined in a return type"); inform (type_location, @@ -5086,24 +5087,27 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) } } - bool complained - = emit_diagnostic (kind, input_location, opt, - "unable to find numeric literal operator %qD", name); - - if (!complained) - /* Don't inform either. */; - else if (i14) - { - inform (token->location, "add %<using namespace std::complex_literals%> " - "(from %<<complex>%>) to enable the C++14 user-defined literal " - "suffixes"); - if (ext) - inform (token->location, "or use %<j%> instead of %<i%> for the " - "GNU built-in suffix"); - } - else if (!ext) - inform (token->location, "use %<-fext-numeric-literals%> " - "to enable more built-in suffixes"); + { + auto_diagnostic_group d; + bool complained + = emit_diagnostic (kind, input_location, opt, + "unable to find numeric literal operator %qD", name); + + if (!complained) + /* Don't inform either. */; + else if (i14) + { + inform (token->location, "add %<using namespace std::complex_literals%> " + "(from %<<complex>%>) to enable the C++14 user-defined literal " + "suffixes"); + if (ext) + inform (token->location, "or use %<j%> instead of %<i%> for the " + "GNU built-in suffix"); + } + else if (!ext) + inform (token->location, "use %<-fext-numeric-literals%> " + "to enable more built-in suffixes"); + } if (kind == DK_ERROR) value = error_mark_node; @@ -7159,6 +7163,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, if (TREE_CODE (tid) == TEMPLATE_ID_EXPR && TREE_CODE (TREE_OPERAND (tid, 0)) != IDENTIFIER_NODE) { + auto_diagnostic_group d; tree tmpl = NULL_TREE; if (is_overloaded_fn (tid)) { @@ -9641,10 +9646,13 @@ cp_parser_new_expression (cp_parser* parser) message for this case. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)) { - error_at (token->location, - "array bound forbidden after parenthesized type-id"); - inform (token->location, - "try removing the parentheses around the type-id"); + { + auto_diagnostic_group d; + error_at (token->location, + "array bound forbidden after parenthesized type-id"); + inform (token->location, + "try removing the parentheses around the type-id"); + } cp_parser_direct_new_declarator (parser); } } @@ -10450,6 +10458,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, && token->type == CPP_RSHIFT && !parser->greater_than_is_operator_p) { + auto_diagnostic_group d; if (warning_at (token->location, OPT_Wc__11_compat, "%<>>%> operator is treated" " as two right angle brackets in C++11")) @@ -11724,6 +11733,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) else if (!VAR_P (capture_init_expr) && TREE_CODE (capture_init_expr) != PARM_DECL) { + auto_diagnostic_group d; error_at (capture_token->location, "capture of non-variable %qE", capture_init_expr); @@ -11735,6 +11745,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) if (VAR_P (capture_init_expr) && decl_storage_duration (capture_init_expr) != dk_auto) { + auto_diagnostic_group d; if (pedwarn (capture_token->location, 0, "capture of variable " "%qD with non-automatic storage duration", capture_init_expr)) @@ -15238,6 +15249,7 @@ cp_parser_module_declaration (cp_parser *parser, module_parse mp_state, } else if (scope != global_namespace) { + auto_diagnostic_group d; error_at (token->location, "module-declaration must be at global scope"); inform (DECL_SOURCE_LOCATION (scope), "scope opened here"); goto skip_eol; @@ -15315,19 +15327,22 @@ cp_parser_import_declaration (cp_parser *parser, module_parse mp_state, if (mp_state == MP_PURVIEW || mp_state == MP_PRIVATE) { + auto_diagnostic_group d; error_at (token->location, "post-module-declaration" " imports must be contiguous"); - note_lexer: inform (token->location, "perhaps insert a line break after" " %<import%>, or other disambiguation, to prevent this" " being considered a module control-line"); - skip_eol: cp_parser_skip_to_pragma_eol (parser, token); } else if (current_scope () != global_namespace) { + auto_diagnostic_group d; error_at (token->location, "import-declaration must be at global scope"); - goto note_lexer; + inform (token->location, "perhaps insert a line break after" + " %<import%>, or other disambiguation, to prevent this" + " being considered a module control-line"); + cp_parser_skip_to_pragma_eol (parser, token); } else { @@ -15355,7 +15370,10 @@ cp_parser_import_declaration (cp_parser *parser, module_parse mp_state, tree attrs = cp_parser_attributes_opt (parser); if (!mod || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)) - goto skip_eol; + { + cp_parser_skip_to_pragma_eol (parser, token); + return; + } cp_parser_require_pragma_eol (parser, token); if (mp_state == MP_PURVIEW_IMPORTS || mp_state == MP_PRIVATE_IMPORTS) @@ -15648,6 +15666,7 @@ cp_parser_declaration (cp_parser* parser, tree prefix_attrs) if (!c_dialect_objc ()) { location_t where = get_finish (t2->location); + auto_diagnostic_group d; warning_at (token1->location, OPT_Wattributes, "attributes are" " not permitted in this position"); where = linemap_position_for_loc_and_offset (line_table, @@ -16899,6 +16918,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, if (decl_specs->std_attributes) { + auto_diagnostic_group d; error_at (decl_specs->locations[ds_std_attribute], "standard attributes in middle of decl-specifiers"); inform (decl_specs->locations[ds_std_attribute], @@ -19148,6 +19168,7 @@ cp_parser_template_id (cp_parser *parser, } /* Otherwise, emit an error about the invalid digraph, but continue parsing because we got our argument list. */ + auto_diagnostic_group d; if (permerror (next_token->location, "%<<::%> cannot begin a template-argument list")) { @@ -19187,6 +19208,7 @@ cp_parser_template_id (cp_parser *parser, /* C++20 says that "function-name < a;" is now ill-formed. */ if (cp_parser_error_occurred (parser)) { + auto_diagnostic_group d; error_at (token->location, "invalid template-argument-list"); inform (token->location, "function name as the left hand " "operand of %<<%> is ill-formed in C++20; wrap the " @@ -19432,10 +19454,13 @@ cp_parser_template_name (cp_parser* parser, cp_token_position start = 0; /* Explain what went wrong. */ - error_at (token->location, "non-template %qD used as template", - identifier); - inform (token->location, "use %<%T::template %D%> to indicate that it is a template", - parser->scope, identifier); + { + auto_diagnostic_group d; + error_at (token->location, "non-template %qD used as template", + identifier); + inform (token->location, "use %<%T::template %D%> to indicate " + "that it is a template", parser->scope, identifier); + } /* If parsing tentatively, find the location of the "<" token. */ if (cp_parser_simulate_error (parser)) start = cp_lexer_token_position (parser->lexer, true); @@ -20103,6 +20128,7 @@ cp_parser_explicit_specialization (cp_parser* parser) bool need_lang_pop = current_lang_name == lang_name_c; if (need_lang_pop) { + auto_diagnostic_group d; error_at (token->location, "template specialization with C linkage"); maybe_show_extern_c_location (); @@ -20935,6 +20961,7 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, { if (!tentative) { + auto_diagnostic_group d; error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); inform (DECL_SOURCE_LOCATION (con), "concept defined here"); } @@ -21548,6 +21575,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, "attributes ignored on template instantiation"); else if (is_friend && cxx11_attribute_p (attributes)) { + auto_diagnostic_group d; if (warning (OPT_Wattributes, "attribute ignored")) inform (input_location, "an attribute that appertains to a friend " "declaration that is not a definition is ignored"); @@ -21900,6 +21928,7 @@ cp_parser_enum_specifier (cp_parser* parser) } else { + auto_diagnostic_group d; error_at (type_start_token->location, "multiple definition of %q#T", type); inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)), @@ -22947,6 +22976,7 @@ cp_parser_asm_definition (cp_parser* parser) case RID_VOLATILE: if (volatile_loc) { + auto_diagnostic_group d; error_at (loc, "duplicate %<asm%> qualifier %qT", token->u.value); inform (volatile_loc, "first seen here"); @@ -22964,6 +22994,7 @@ cp_parser_asm_definition (cp_parser* parser) case RID_INLINE: if (inline_loc) { + auto_diagnostic_group d; error_at (loc, "duplicate %<asm%> qualifier %qT", token->u.value); inform (inline_loc, "first seen here"); @@ -22978,6 +23009,7 @@ cp_parser_asm_definition (cp_parser* parser) case RID_GOTO: if (goto_loc) { + auto_diagnostic_group d; error_at (loc, "duplicate %<asm%> qualifier %qT", token->u.value); inform (goto_loc, "first seen here"); @@ -23791,12 +23823,13 @@ cp_parser_init_declarator (cp_parser* parser, attributes -- but ignores them. Made a permerror in GCC 8. */ if (cp_parser_allow_gnu_extensions_p (parser) && initialization_kind == CPP_OPEN_PAREN - && cp_parser_attributes_opt (parser) - && permerror (input_location, - "attributes after parenthesized initializer ignored")) + && cp_parser_attributes_opt (parser)) { static bool hint; - if (flag_permissive && !hint) + auto_diagnostic_group d; + if (permerror (input_location, + "attributes after parenthesized initializer ignored") + && flag_permissive && !hint) { hint = true; inform (input_location, @@ -24496,6 +24529,7 @@ cp_parser_direct_declarator (cp_parser* parser, else if (qualifying_scope && CLASSTYPE_USE_TEMPLATE (name_type)) { + auto_diagnostic_group d; error_at (declarator_id_start_token->location, "invalid use of constructor as a template"); inform (declarator_id_start_token->location, @@ -27890,6 +27924,7 @@ cp_parser_class_head (cp_parser* parser, if (type != error_mark_node && (COMPLETE_TYPE_P (type) || TYPE_BEING_DEFINED (type))) { + auto_diagnostic_group d; error_at (type_start_token->location, "redefinition of %q#T", type); inform (location_of (type), "previous definition of %q#T", @@ -28344,6 +28379,7 @@ cp_parser_member_declaration (cp_parser* parser) && cxx11_attribute_p (decl_specifiers.attributes)) { decl_specifiers.attributes = NULL_TREE; + auto_diagnostic_group d; if (warning_at (decl_spec_token_start->location, OPT_Wattributes, "attribute ignored")) inform (decl_spec_token_start->location, "an attribute " @@ -32449,6 +32485,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, cp_parser_error, so we incorporate its actions directly. */ if (!cp_parser_simulate_error (parser)) { + auto_diagnostic_group d; error_at (name_location, "reference to %qD is ambiguous", name); print_candidates (decl); @@ -33260,6 +33297,7 @@ cp_parser_explicit_template_declaration (cp_parser* parser, bool member_p) A template ... shall not have C linkage. */ if (current_lang_name == lang_name_c) { + auto_diagnostic_group d; error_at (location, "template with C linkage"); maybe_show_extern_c_location (); /* Give it C++ linkage to avoid confusing other parts of the @@ -35236,6 +35274,7 @@ cp_parser_check_class_key (cp_parser *parser, location_t key_loc, bool seen_as_union = TREE_CODE (type) == UNION_TYPE; if (seen_as_union != (class_key == union_type)) { + auto_diagnostic_group d; if (permerror (input_location, "%qs tag used in naming %q#T", class_key == union_type ? "union" : class_key == record_type ? "struct" : "class", diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 024fa8a5529..f60b1069d6d 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -1124,6 +1124,7 @@ maybe_process_partial_specialization (tree type) if (current_namespace != decl_namespace_context (tmpl)) { + auto_diagnostic_group d; if (permerror (input_location, "specialization of %qD in different namespace", type)) @@ -2471,6 +2472,7 @@ determine_specialization (tree template_id, if (templates == NULL_TREE && candidates == NULL_TREE) { + auto_diagnostic_group d; error ("template-id %qD for %q+D does not match any template " "declaration", template_id, decl); if (header_mismatch) @@ -2485,6 +2487,7 @@ determine_specialization (tree template_id, || (candidates && TREE_CHAIN (candidates)) || (templates && candidates)) { + auto_diagnostic_group d; error ("ambiguous template specialization %qD for %q+D", template_id, decl); candidates = chainon (candidates, templates); @@ -4311,6 +4314,7 @@ check_for_bare_parameter_packs (tree t, location_t loc /* = UNKNOWN_LOCATION */) if (parameter_packs) { + auto_diagnostic_group d; error_at (loc, "parameter packs not expanded with %<...%>:"); while (parameter_packs) { @@ -4455,6 +4459,7 @@ check_template_shadow (tree decl) if (DECL_SELF_REFERENCE_P (decl)) return false; + auto_diagnostic_group d; if (DECL_TEMPLATE_PARM_P (decl)) error ("declaration of template parameter %q+D shadows " "template parameter", decl); @@ -5141,7 +5146,6 @@ process_partial_specialization (tree decl) int nargs = TREE_VEC_LENGTH (inner_args); int ntparms; int i; - bool did_error_intro = false; struct template_parm_data tpd; struct template_parm_data tpd2; @@ -5195,24 +5199,29 @@ process_partial_specialization (tree decl) NULL, /*include_nondeduced_p=*/false); } - for (i = 0; i < ntparms; ++i) - if (tpd.parms[i] == 0) - { - /* One of the template parms was not used in a deduced context in the - specialization. */ - if (!did_error_intro) - { - error ("template parameters not deducible in " - "partial specialization:"); - did_error_intro = true; - } - inform (input_location, " %qD", - TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); - } + { + auto_diagnostic_group d; + bool did_error_intro = false; + for (i = 0; i < ntparms; ++i) + if (tpd.parms[i] == 0) + { + /* One of the template parms was not used in a deduced context in the + specialization. */ + if (!did_error_intro) + { + error ("template parameters not deducible in " + "partial specialization:"); + did_error_intro = true; + } - if (did_error_intro) - return error_mark_node; + inform (input_location, " %qD", + TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); + } + + if (did_error_intro) + return error_mark_node; + } /* [temp.class.spec] @@ -5224,6 +5233,7 @@ process_partial_specialization (tree decl) && (!flag_concepts || !strictly_subsumes (current_template_constraints (), maintmpl))) { + auto_diagnostic_group d; if (!flag_concepts) error ("partial specialization %q+D does not specialize " "any template arguments; to define the primary template, " @@ -5241,6 +5251,7 @@ process_partial_specialization (tree decl) parameters. */ if (nargs < DECL_NTPARMS (maintmpl)) { + auto_diagnostic_group d; error ("partial specialization is not more specialized than the " "primary template because it replaces multiple parameters " "with a pack expansion"); @@ -5251,6 +5262,7 @@ process_partial_specialization (tree decl) else if (nargs > DECL_NTPARMS (maintmpl)) { + auto_diagnostic_group d; error ("too many arguments for partial specialization %qT", type); inform (DECL_SOURCE_LOCATION (maintmpl), "primary template here"); /* Avoid crash below. */ @@ -6141,6 +6153,7 @@ push_template_decl (tree decl, bool is_friend) (TI_ARGS (tinfo), TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl))))) { + auto_diagnostic_group d; error ("template arguments to %qD do not match original " "template %qD", decl, DECL_TEMPLATE_RESULT (tmpl)); if (!uses_template_parms (TI_ARGS (tinfo))) @@ -6346,6 +6359,7 @@ redeclare_class_template (tree type, tree parms, tree cons) if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms)) { + auto_diagnostic_group d; error_n (input_location, TREE_VEC_LENGTH (parms), "redeclared with %d template parameter", "redeclared with %d template parameters", @@ -6862,6 +6876,7 @@ convert_nontype_argument_function (tree type, tree expr, { if (complain & tf_error) { + auto_diagnostic_group d; location_t loc = cp_expr_loc_or_input_loc (expr); error_at (loc, "%qE is not a valid template argument for type %qT", expr, type); @@ -6932,6 +6947,7 @@ check_valid_ptrmem_cst_expr (tree type, tree expr, return true; if (complain & tf_error) { + auto_diagnostic_group d; location_t loc = cp_expr_loc_or_input_loc (orig_expr); error_at (loc, "%qE is not a valid template argument for type %qT", orig_expr, type); @@ -7805,6 +7821,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (complain & tf_error) { + auto_diagnostic_group d; error ("%qE is not a valid template argument for type %qT " "because it is a pointer", expr, type); inform (input_location, "try using %qE instead", @@ -8663,6 +8680,7 @@ convert_template_argument (tree parm, { if (complain & tf_error) { + auto_diagnostic_group d; error ("type/value mismatch at argument %d in template " "parameter list for %qD", i + 1, in_decl); @@ -8697,6 +8715,7 @@ convert_template_argument (tree parm, { if (in_decl && (complain & tf_error)) { + auto_diagnostic_group d; error ("type/value mismatch at argument %d in template " "parameter list for %qD", i + 1, in_decl); @@ -8747,6 +8766,7 @@ convert_template_argument (tree parm, { if (in_decl && (complain & tf_error)) { + auto_diagnostic_group d; error ("type/value mismatch at argument %d in " "template parameter list for %qD", i + 1, in_decl); @@ -8765,6 +8785,7 @@ convert_template_argument (tree parm, { if (in_decl && (complain & tf_error)) { + auto_diagnostic_group d; error ("constraint mismatch at argument %d in " "template parameter list for %qD", i + 1, in_decl); @@ -9147,6 +9168,7 @@ coerce_template_parms (tree parms, bad_nargs: if (complain & tf_error) { + auto_diagnostic_group d; if (variadic_p || default_p) { nparms -= variadic_p + default_p; @@ -9182,6 +9204,7 @@ coerce_template_parms (tree parms, if (PACK_EXPANSION_P (arg) && !template_parameter_pack_p (parm)) { + auto_diagnostic_group d; if (DECL_ALIAS_TEMPLATE_P (in_decl)) error_at (location_of (arg), "pack expansion argument for non-pack parameter " @@ -17373,6 +17396,7 @@ tsubst_qualified_id (tree qualified_id, tree args, { if (complain & tf_error) { + auto_diagnostic_group d; error ("dependent-name %qE is parsed as a non-type, but " "instantiation yields a type", qualified_id); inform (input_location, "say %<typename %E%> if a type is meant", qualified_id); @@ -20965,6 +20989,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (unq != function) { + auto_diagnostic_group d; char const *const msg = G_("%qD was not declared in this scope, " "and no declarations were found by " @@ -26400,6 +26425,7 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain, char *spaces = NULL; if (!(complain & tf_error)) return error_mark_node; + auto_diagnostic_group d; if (TYPE_P (target)) error ("ambiguous template instantiation for %q#T", target); else @@ -30866,6 +30892,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, { /* Be permissive with equivalent alias templates. */ tree u = get_underlying_template (tmpl); + auto_diagnostic_group d; diagnostic_t dk = (u == tmpl) ? DK_ERROR : DK_PEDWARN; bool complained = emit_diagnostic (dk, input_location, 0, @@ -31022,6 +31049,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, { if (complain & tf_warning_or_error) { + auto_diagnostic_group d; error ("class template argument deduction failed:"); perform_dguide_overload_resolution (cands, args, complain); if (elided) @@ -31039,6 +31067,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, if (complain & tf_warning_or_error) { // TODO: Pass down location from cp_finish_decl. + auto_diagnostic_group d; error ("class template argument deduction for %qT failed: " "explicit deduction guide selected in " "copy-list-initialization", type); @@ -31054,6 +31083,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, guides, this deduction might not be what the user intended. */ if (fndecl != error_mark_node && !any_dguides_p && (complain & tf_warning)) { + auto_diagnostic_group d; if ((!DECL_IN_SYSTEM_HEADER (fndecl) || global_dc->m_warn_system_headers) && warning (OPT_Wctad_maybe_unsupported, @@ -31181,6 +31211,7 @@ do_auto_deduction (tree type, tree init, tree auto_node, { if (complain & tf_warning_or_error) { + auto_diagnostic_group d; if (permerror (loc, "direct-list-initialization of " "%<auto%> requires exactly one element")) inform (loc, diff --git a/gcc/cp/search.cc b/gcc/cp/search.cc index 827f48e8604..60c30ecb881 100644 --- a/gcc/cp/search.cc +++ b/gcc/cp/search.cc @@ -1227,6 +1227,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type, { if (complain & tf_error) { + auto_diagnostic_group d; error ("request for member %qD is ambiguous", name); print_candidates (lfi.ambiguous); } diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 5ab2076b673..3e117c216da 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -2383,6 +2383,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope, { if (complain & tf_error) { + auto_diagnostic_group d; if (current_function_decl && DECL_STATIC_FUNCTION_P (current_function_decl)) error ("invalid use of member %qD in static member function", decl); @@ -4248,6 +4249,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use) { if (complain & tf_error) { + auto_diagnostic_group d; error ("%qD is not captured", decl); tree closure = LAMBDA_EXPR_CLOSURE (lambda_expr); if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE) @@ -4268,6 +4270,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use) { if (complain & tf_error) { + auto_diagnostic_group d; error (VAR_P (decl) ? G_("use of local variable with automatic storage from " "containing function") @@ -4503,6 +4506,7 @@ finish_id_expression_1 (tree id_expression, if (TREE_CODE (decl) == TREE_LIST) { /* Ambiguous reference to base members. */ + auto_diagnostic_group d; error ("request for member %qD is ambiguous in " "multiple inheritance lattice", id_expression); print_candidates (decl); @@ -4909,6 +4913,7 @@ finish_offsetof (tree object_ptr, tree expr, location_t loc) if (DECL_P (expr)) { + auto_diagnostic_group d; error ("cannot apply %<offsetof%> to member function %qD", expr); inform (DECL_SOURCE_LOCATION (expr), "declared here"); } @@ -6321,6 +6326,7 @@ omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp, return ret; if (!ambiguous.is_empty ()) { + auto_diagnostic_group d; const char *str = _("candidates are:"); unsigned int idx; tree udr; @@ -8393,6 +8399,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) && !type_dependent_expression_p (t) && !omp_mappable_type (TREE_TYPE (t))) { + auto_diagnostic_group d; error_at (OMP_CLAUSE_LOCATION (c), "array section does not have mappable type " "in %qs clause", @@ -8615,6 +8622,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) ? TREE_TYPE (TREE_TYPE (t)) : TREE_TYPE (t))) { + auto_diagnostic_group d; error_at (OMP_CLAUSE_LOCATION (c), "%qD does not have a mappable type in %qs clause", t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); @@ -8782,6 +8790,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } else if (!omp_mappable_type (TREE_TYPE (t))) { + auto_diagnostic_group d; error_at (OMP_CLAUSE_LOCATION (c), "%qD does not have a mappable type in %qs clause", t, cname); diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index 31ecbb1ac79..c3a38de4f48 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -5223,6 +5223,7 @@ check_abi_tag_redeclaration (const_tree decl, const_tree old, const_tree new_) if (new_ && TREE_CODE (TREE_VALUE (new_)) == TREE_LIST) new_ = TREE_VALUE (new_); bool err = false; + auto_diagnostic_group d; for (const_tree t = new_; t; t = TREE_CHAIN (t)) { tree str = TREE_VALUE (t); @@ -5276,6 +5277,7 @@ check_abi_tag_args (tree args, tree name) { if (!ISALPHA (c) && c != '_') { + auto_diagnostic_group d; error ("arguments to the %qE attribute must contain valid " "identifiers", name); inform (input_location, "%<%c%> is not a valid first " @@ -5289,6 +5291,7 @@ check_abi_tag_args (tree args, tree name) { if (!ISALNUM (c) && c != '_') { + auto_diagnostic_group d; error ("arguments to the %qE attribute must contain valid " "identifiers", name); inform (input_location, "%<%c%> is not a valid character " diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index f26b5b2a1f4..e4e260645f6 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -2365,6 +2365,7 @@ invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain) { if (DECL_P (expr)) { + auto_diagnostic_group d; error_at (loc, "invalid use of non-static member function %qD", expr); inform (DECL_SOURCE_LOCATION (expr), "declared here"); @@ -3309,6 +3310,7 @@ complain_about_unrecognized_member (tree access_path, tree name, { /* The guessed name isn't directly accessible, and no accessor member function could be found. */ + auto_diagnostic_group d; error_at (&rich_loc, "%q#T has no member named %qE;" " did you mean %q#D? (not accessible from this context)", @@ -3534,21 +3536,24 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, else { /* Look up the member. */ - access_failure_info afi; - if (processing_template_decl) - /* Even though this class member access expression is at this - point not dependent, the member itself may be dependent, and - we must not potentially push a access check for a dependent - member onto TI_DEFERRED_ACCESS_CHECKS. So don't check access - ahead of time here; we're going to redo this member lookup at - instantiation time anyway. */ - push_deferring_access_checks (dk_no_check); - member = lookup_member (access_path, name, /*protect=*/1, - /*want_type=*/false, complain, - &afi); - if (processing_template_decl) - pop_deferring_access_checks (); - afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); + { + auto_diagnostic_group d; + access_failure_info afi; + if (processing_template_decl) + /* Even though this class member access expression is at this + point not dependent, the member itself may be dependent, and + we must not potentially push a access check for a dependent + member onto TI_DEFERRED_ACCESS_CHECKS. So don't check access + ahead of time here; we're going to redo this member lookup at + instantiation time anyway. */ + push_deferring_access_checks (dk_no_check); + member = lookup_member (access_path, name, /*protect=*/1, + /*want_type=*/false, complain, + &afi); + if (processing_template_decl) + pop_deferring_access_checks (); + afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); + } if (member == NULL_TREE) { if (dependentish_scope_p (object_type)) @@ -4504,6 +4509,7 @@ error_args_num (location_t loc, tree fndecl, bool too_many_p) { if (fndecl) { + auto_diagnostic_group d; if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE) { if (DECL_NAME (fndecl) == NULL_TREE @@ -4952,6 +4958,7 @@ warn_for_null_address (location_t location, tree op, tsubst_flags_t complain) STRIP_NOPS (cop); } + auto_diagnostic_group d; bool warned = false; if (TREE_CODE (cop) == ADDR_EXPR) { @@ -6106,6 +6113,7 @@ cp_build_binary_op (const op_location_t &location, { if (complain & tf_error) { + auto_diagnostic_group d; error_at (location, "comparing vectors with different " "element types"); inform (location, "operand types are %qT and %qT", @@ -6119,6 +6127,7 @@ cp_build_binary_op (const op_location_t &location, { if (complain & tf_error) { + auto_diagnostic_group d; error_at (location, "comparing vectors with different " "number of elements"); inform (location, "operand types are %qT and %qT", @@ -6964,6 +6973,7 @@ build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg, { if (complain & tf_error) { + auto_diagnostic_group d; error_at (loc, "invalid use of %qE to form a " "pointer-to-member-function", xarg.get_value ()); if (TREE_CODE (xarg) != OFFSET_REF) @@ -7498,10 +7508,13 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert, { /* Warn if the expression has boolean value. */ if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE - && (complain & tf_warning) - && warning_at (location, OPT_Wbool_operation, - "%<~%> on an expression of type %<bool%>")) - inform (location, "did you mean to use logical not (%<!%>)?"); + && (complain & tf_warning)) + { + auto_diagnostic_group d; + if (warning_at (location, OPT_Wbool_operation, + "%<~%> on an expression of type %<bool%>")) + inform (location, "did you mean to use logical not (%<!%>)?"); + } arg = cp_perform_integral_promotions (arg, complain); } else if (!noconvert && VECTOR_TYPE_P (TREE_TYPE (arg))) @@ -8723,6 +8736,7 @@ build_static_cast (location_t loc, tree type, tree oexpr, if (complain & tf_error) { + auto_diagnostic_group d; error_at (loc, "invalid %<static_cast%> from type %qT to type %qT", TREE_TYPE (expr), type); if ((TYPE_PTR_P (type) || TYPE_REF_P (type)) @@ -9682,15 +9696,19 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, rhs = decay_conversion (rhs, complain); if (rhs == error_mark_node) return error_mark_node; - rhs = stabilize_expr (rhs, &init); - newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain); - if (newrhs == error_mark_node) - { - if (complain & tf_error) - inform (loc, " in evaluation of %<%Q(%#T, %#T)%>", - modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs)); - return error_mark_node; - } + + { + auto_diagnostic_group d; + rhs = stabilize_expr (rhs, &init); + newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain); + if (newrhs == error_mark_node) + { + if (complain & tf_error) + inform (loc, " in evaluation of %<%Q(%#T, %#T)%>", + modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs)); + return error_mark_node; + } + } if (init) newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs); @@ -9970,6 +9988,7 @@ get_delta_difference (tree from, tree to, bool allow_inverse_p, bool c_cast_p, tsubst_flags_t complain) { + auto_diagnostic_group d; tree result; if (same_type_ignoring_top_level_qualifiers_p (from, to)) @@ -10384,6 +10403,8 @@ convert_for_assignment (tree type, tree rhs, { if (complain & tf_error) { + auto_diagnostic_group d; + /* If the right-hand side has unknown type, then it is an overloaded function. Call instantiate_type to get error messages. */ @@ -10406,7 +10427,6 @@ convert_for_assignment (tree type, tree rhs, (rhs_loc, has_loc ? &label : NULL, has_loc ? highlight_colors::percent_h : NULL); - auto_diagnostic_group d; switch (errtype) { @@ -11150,6 +11170,7 @@ check_return_expr (tree retval, bool *no_warning, bool *dangling) if (!retval && !is_auto (pattern)) { /* Give a helpful error message. */ + auto_diagnostic_group d; error ("return-statement with no value, in function returning %qT", pattern); inform (input_location, "only plain %<auto%> return type can be " diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc index a0c8f833ac1..79b397a69fa 100644 --- a/gcc/cp/typeck2.cc +++ b/gcc/cp/typeck2.cc @@ -302,6 +302,7 @@ cxx_incomplete_type_diagnostic (location_t loc, const_tree value, if (TREE_CODE (type) == ERROR_MARK) return false; + auto_diagnostic_group d; if (value) { STRIP_ANY_LOCATION_WRAPPER (value);
On 9/2/24 7:43 AM, Nathaniel Shead wrote: > Ping for https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659796.html OK. > For clarity's sake, here's the full patch with the adjustment I > mentioned earlier: > > -- >8 -- > > This patch goes through all .cc files in gcc/cp and adds in any > auto_diagnostic_groups that seem to be missing by looking for any > 'inform' calls that aren't grouped with their respective error/warning. > Now with SARIF output support this seems to be a bit more important. > > The patch isn't complete; I've tried to also track helper functions used > for diagnostics to group them, but some may have been missed. > Additionally there are a few functions that are definitely missing > groupings but I wasn't able to see an obvious way to add them without > potentially grouping together unrelated messages. > > This list includes: > > - lazy_load_{binding,pendings} "during load of {binding,pendings} for" > - cp_finish_decomp "in initialization of structured binding variable" > - require_deduced_type "using __builtin_source_location" > - convert_nontype_argument "in template argument for type %qT" > - coerce_template_params "so any instantiation with a non-empty parameter pack" > - tsubst_default_argument "when instantiating default argument" > - invalid_nontype_parm_type_p "invalid template non-type parameter" > > gcc/cp/ChangeLog: > > * class.cc (add_method): Add missing auto_diagnostic_group. > (handle_using_decl): Likewise. > (maybe_warn_about_overly_private_class): Likewise. > (check_field_decl): Likewise. > (check_field_decls): Likewise. > (resolve_address_of_overloaded_function): Likewise. > (note_name_declared_in_class): Likewise. > * constraint.cc (associate_classtype_constraints): Likewise. > (diagnose_trait_expr): Clean up whitespace. > * coroutines.cc (find_coro_traits_template_decl): Add missing > auto_diagnostic_group. > (coro_promise_type_found_p): Likewise. > (coro_diagnose_throwing_fn): Likewise. > * cvt.cc (build_expr_type_conversion): Likewise. > * decl.cc (validate_constexpr_redeclaration): Likewise. > (duplicate_function_template_decls): Likewise. > (duplicate_decls): Likewise. > (lookup_label_1): Likewise. > (check_previous_goto_1): Likewise. > (check_goto_1): Likewise. > (make_typename_type): Likewise. > (make_unbound_class_template): Likewise. > (check_tag_decl): Likewise. > (start_decl): Likewise. > (maybe_commonize_var): Likewise. > (check_for_uninitialized_const_var): Likewise. > (reshape_init_class): Likewise. > (check_initializer): Likewise. > (cp_finish_decl): Likewise. > (find_decomp_class_base): Likewise. > (cp_finish_decomp): Likewise. > (expand_static_init): Likewise. > (grokfndecl): Likewise. > (grokdeclarator): Likewise. > (check_elaborated_type_specifier): Likewise. > (lookup_and_check_tag): Likewise. > (xref_tag): Likewise. > (cxx_simulate_enum_decl): Likewise. > (finish_function): Likewise. > * decl2.cc (check_classfn): Likewise. > (record_mangling): Likewise. > (mark_used): Likewise. > * error.cc (qualified_name_lookup_error): Likewise. > * except.cc (build_throw): Likewise. > * init.cc (get_nsdmi): Likewise. > (diagnose_uninitialized_cst_or_ref_member_1): Likewise. > (warn_placement_new_too_small): Likewise. > (build_new_1): Likewise. > (build_vec_delete_1): Likewise. > (build_delete): Likewise. > * lambda.cc (add_capture): Likewise. > (add_default_capture): Likewise. > * lex.cc (unqualified_fn_lookup_error): Likewise. > * method.cc (synthesize_method): Likewise. > (defaulted_late_check): Likewise. > * module.cc (trees_in::is_matching_decl): Likewise. > (trees_in::read_enum_def): Likewise. > (module_state::check_not_purview): Likewise. > (module_state::deferred_macro): Likewise. > (module_state::read_config): Likewise. > (module_state::check_read): Likewise. > (declare_module): Likewise. > (init_modules): Likewise. > * name-lookup.cc (diagnose_name_conflict): Likewise. > (lookup_using_decl): Likewise. > (set_decl_namespace): Likewise. > (finish_using_directive): Likewise. > (push_namespace): Likewise. > (add_imported_namespace): Likewise. > * parser.cc (cp_parser_check_for_definition_in_return_type): Likewise. > (cp_parser_userdef_numeric_literal): Likewise. > (cp_parser_nested_name_specifier_opt): Likewise. > (cp_parser_new_expression): Likewise. > (cp_parser_binary_expression): Likewise. > (cp_parser_lambda_introducer): Likewise. > (cp_parser_module_declaration): Likewise. > (cp_parser_import_declaration): Likewise, removing gotos to > support this. > (cp_parser_declaration): Add missing auto_diagnostic_group. > (cp_parser_decl_specifier_seq): Likewise. > (cp_parser_template_id): Likewise. > (cp_parser_template_name): Likewise. > (cp_parser_explicit_specialization): Likewise. > (cp_parser_placeholder_type_specifier): Likewise. > (cp_parser_elaborated_type_specifier): Likewise. > (cp_parser_enum_specifier): Likewise. > (cp_parser_asm_definition): Likewise. > (cp_parser_init_declarator): Likewise. > (cp_parser_direct_declarator): Likewise. > (cp_parser_class_head): Likewise. > (cp_parser_member_declaration): Likewise. > (cp_parser_lookup_name): Likewise. > (cp_parser_explicit_template_declaration): Likewise. > (cp_parser_check_class_key): Likewise. > * pt.cc (maybe_process_partial_specialization): Likewise. > (determine_specialization): Likewise. > (check_for_bare_parameter_packs): Likewise. > (check_template_shadow): Likewise. > (process_partial_specialization): Likewise. > (push_template_decl): Likewise. > (redeclare_class_template): Likewise. > (convert_nontype_argument_function): Likewise. > (check_valid_ptrmem_cst_expr): Likewise. > (convert_nontype_argument): Likewise. > (convert_template_argument): Likewise. > (coerce_template_parms): Likewise. > (tsubst_qualified_id): Likewise. > (tsubst_expr): Likewise. > (most_specialized_partial_spec): Likewise. > (do_class_deduction): Likewise. > (do_auto_deduction): Likewise. > * search.cc (lookup_member): Likewise. > * semantics.cc (finish_non_static_data_member): Likewise. > (process_outer_var_ref): Likewise. > (finish_id_expression_1): Likewise. > (finish_offsetof): Likewise. > (omp_reduction_lookup): Likewise. > (finish_omp_clauses): Likewise. > * tree.cc (check_abi_tag_redeclaration): Likewise. > (check_abi_tag_args): Likewise. > * typeck.cc (invalid_nonstatic_memfn_p): Likewise. > (complain_about_unrecognized_member): Likewise. > (finish_class_member_access_expr): Likewise. > (error_args_num): Likewise. > (warn_for_null_address): Likewise. > (cp_build_binary_op): Likewise. > (build_x_unary_op): Likewise. > (cp_build_unary_op): Likewise. > (build_static_cast): Likewise. > (cp_build_modify_expr): Likewise. > (get_delta_difference): Likewise. > (convert_for_assignment): Widen scope of auto_diagnostic_group. > (check_return_expr): Add missing auto_diagnostic_group. > * typeck2.cc (cxx_incomplete_type_diagnostic): Likewise. > > Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> > Reviewed-by: Marek Polacek <polacek@redhat.com> > --- > gcc/cp/class.cc | 12 +++++ > gcc/cp/constraint.cc | 21 +++++---- > gcc/cp/coroutines.cc | 3 ++ > gcc/cp/cvt.cc | 1 + > gcc/cp/decl.cc | 59 +++++++++++++++++++++-- > gcc/cp/decl2.cc | 3 ++ > gcc/cp/error.cc | 2 + > gcc/cp/except.cc | 1 + > gcc/cp/init.cc | 8 ++++ > gcc/cp/lambda.cc | 3 ++ > gcc/cp/lex.cc | 1 + > gcc/cp/method.cc | 3 ++ > gcc/cp/module.cc | 8 ++++ > gcc/cp/name-lookup.cc | 7 +++ > gcc/cp/parser.cc | 107 ++++++++++++++++++++++++++++-------------- > gcc/cp/pt.cc | 65 ++++++++++++++++++------- > gcc/cp/search.cc | 1 + > gcc/cp/semantics.cc | 9 ++++ > gcc/cp/tree.cc | 3 ++ > gcc/cp/typeck.cc | 79 +++++++++++++++++++------------ > gcc/cp/typeck2.cc | 1 + > 21 files changed, 303 insertions(+), 94 deletions(-) > > diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc > index fb6c3370950..950d83b0ea4 100644 > --- a/gcc/cp/class.cc > +++ b/gcc/cp/class.cc > @@ -1431,6 +1431,7 @@ add_method (tree type, tree method, bool via_using) > continue; > } > > + auto_diagnostic_group d; > error_at (DECL_SOURCE_LOCATION (method), > "%q#D conflicts with version inherited from %qT", > method, basef); > @@ -1453,6 +1454,7 @@ add_method (tree type, tree method, bool via_using) > } > else > { > + auto_diagnostic_group d; > error_at (DECL_SOURCE_LOCATION (method), > "%q#D cannot be overloaded with %q#D", method, fn); > inform (DECL_SOURCE_LOCATION (fn), > @@ -1604,6 +1606,7 @@ handle_using_decl (tree using_decl, tree t) > ; > else if (is_overloaded_fn (old_value)) > { > + auto_diagnostic_group d; > error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T " > "because of local method %q#D with same name", > using_decl, t, old_value); > @@ -1613,6 +1616,7 @@ handle_using_decl (tree using_decl, tree t) > } > else if (!DECL_ARTIFICIAL (old_value)) > { > + auto_diagnostic_group d; > error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T " > "because of local member %q#D with same name", > using_decl, t, old_value); > @@ -2547,6 +2551,7 @@ maybe_warn_about_overly_private_class (tree t) > > if (!nonprivate_ctor) > { > + auto_diagnostic_group d; > bool w = warning (OPT_Wctor_dtor_privacy, > "%q#T only defines private constructors and has " > "no friends", t); > @@ -3815,6 +3820,7 @@ check_field_decl (tree field, > if (TREE_CODE (t) == UNION_TYPE && cxx_dialect < cxx11) > { > static bool warned; > + auto_diagnostic_group d; > int oldcount = errorcount; > if (TYPE_NEEDS_CONSTRUCTING (type)) > error ("member %q+#D with constructor not allowed in union", > @@ -4131,6 +4137,7 @@ check_field_decls (tree t, tree *access_decls, > if (default_init_member > && TREE_CODE (t) == UNION_TYPE) > { > + auto_diagnostic_group d; > error ("multiple fields in union %qT initialized", t); > inform (DECL_SOURCE_LOCATION (default_init_member), > "initialized member %q+D declared here", > @@ -4209,6 +4216,7 @@ check_field_decls (tree t, tree *access_decls, > && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) > && !(TYPE_HAS_COPY_CTOR (t) && TYPE_HAS_COPY_ASSIGN (t))) > { > + auto_diagnostic_group d; > if (warning (OPT_Weffc__, "%q#T has pointer data members", t)) > { > if (! TYPE_HAS_COPY_CTOR (t)) > @@ -8913,6 +8921,7 @@ resolve_address_of_overloaded_function (tree target_type, > /* There were *no* matches. */ > if (complain & tf_error) > { > + auto_diagnostic_group d; > error ("no matches converting function %qD to type %q#T", > OVL_NAME (overload), target_type); > > @@ -8940,6 +8949,7 @@ resolve_address_of_overloaded_function (tree target_type, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error ("converting overloaded function %qD to type %q#T is ambiguous", > OVL_NAME (overload), target_type); > > @@ -9397,6 +9407,8 @@ note_name_declared_in_class (tree name, tree decl) > else > /* Make it an error. */ > global_dc->m_pedantic_errors = 1; > + > + auto_diagnostic_group d; > if (pedwarn (location_of (decl), OPT_Wchanges_meaning, > "declaration of %q#D changes meaning of %qD", > decl, OVL_NAME (decl))) > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc > index f79407f2cdb..ebfcdefd284 100644 > --- a/gcc/cp/constraint.cc > +++ b/gcc/cp/constraint.cc > @@ -1005,6 +1005,7 @@ associate_classtype_constraints (tree type) > } > if (!equivalent_constraints (ci, orig_ci)) > { > + auto_diagnostic_group d; > error ("%qT does not match original declaration", type); > tree tmpl = CLASSTYPE_TI_TEMPLATE (type); > location_t loc = DECL_SOURCE_LOCATION (tmpl); > @@ -3183,9 +3184,9 @@ diagnose_trait_expr (tree expr, tree args) > break; > case CPTK_IS_CONSTRUCTIBLE: > if (!t2) > - inform (loc, " %qT is not default constructible", t1); > + inform (loc, " %qT is not default constructible", t1); > else > - inform (loc, " %qT is not constructible from %qE", t1, t2); > + inform (loc, " %qT is not constructible from %qE", t1, t2); > break; > case CPTK_IS_CONVERTIBLE: > inform (loc, " %qT is not convertible from %qE", t2, t1); > @@ -3204,9 +3205,9 @@ diagnose_trait_expr (tree expr, tree args) > break; > case CPTK_IS_INVOCABLE: > if (!t2) > - inform (loc, " %qT is not invocable", t1); > + inform (loc, " %qT is not invocable", t1); > else > - inform (loc, " %qT is not invocable by %qE", t1, t2); > + inform (loc, " %qT is not invocable by %qE", t1, t2); > break; > case CPTK_IS_LAYOUT_COMPATIBLE: > inform (loc, " %qT is not layout compatible with %qT", t1, t2); > @@ -3233,14 +3234,14 @@ diagnose_trait_expr (tree expr, tree args) > inform (loc, " %qT is not nothrow constructible from %qE", t1, t2); > break; > case CPTK_IS_NOTHROW_CONVERTIBLE: > - inform (loc, " %qT is not nothrow convertible from %qE", t2, t1); > + inform (loc, " %qT is not nothrow convertible from %qE", t2, t1); > break; > case CPTK_IS_NOTHROW_INVOCABLE: > - if (!t2) > - inform (loc, " %qT is not nothrow invocable", t1); > - else > - inform (loc, " %qT is not nothrow invocable by %qE", t1, t2); > - break; > + if (!t2) > + inform (loc, " %qT is not nothrow invocable", t1); > + else > + inform (loc, " %qT is not nothrow invocable by %qE", t1, t2); > + break; > case CPTK_IS_OBJECT: > inform (loc, " %qT is not an object type", t1); > break; > diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc > index 20bda5520c0..e605eaec7a4 100644 > --- a/gcc/cp/coroutines.cc > +++ b/gcc/cp/coroutines.cc > @@ -305,6 +305,7 @@ find_coro_traits_template_decl (location_t kw) > { > if (!traits_error_emitted) > { > + auto_diagnostic_group d; > gcc_rich_location richloc (kw); > error_at (&richloc, "coroutines require a traits template; cannot" > " find %<%E::%E%>", std_node, coro_traits_identifier); > @@ -632,6 +633,7 @@ coro_promise_type_found_p (tree fndecl, location_t loc) > tf_none); > if (has_ret_void && has_ret_val) > { > + auto_diagnostic_group d; > location_t ploc = DECL_SOURCE_LOCATION (fndecl); > if (!coro_info->coro_co_return_error_emitted) > error_at (ploc, "the coroutine promise type %qT declares both" > @@ -1025,6 +1027,7 @@ coro_diagnose_throwing_fn (tree fndecl) > { > if (!TYPE_NOTHROW_P (TREE_TYPE (fndecl))) > { > + auto_diagnostic_group d; > location_t f_loc = cp_expr_loc_or_loc (fndecl, > DECL_SOURCE_LOCATION (fndecl)); > error_at (f_loc, "the expression %qE is required to be non-throwing", > diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc > index 7b4bd8a9dc4..df02b8faaf5 100644 > --- a/gcc/cp/cvt.cc > +++ b/gcc/cp/cvt.cc > @@ -1933,6 +1933,7 @@ build_expr_type_conversion (int desires, tree expr, bool complain) > { > if (complain) > { > + auto_diagnostic_group d; > error ("ambiguous default type conversion from %qT", > basetype); > inform (input_location, > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc > index 6458e96bded..7bad3047ad9 100644 > --- a/gcc/cp/decl.cc > +++ b/gcc/cp/decl.cc > @@ -1457,6 +1457,7 @@ validate_constexpr_redeclaration (tree old_decl, tree new_decl) > if (DECL_IMMEDIATE_FUNCTION_P (old_decl) > || DECL_IMMEDIATE_FUNCTION_P (new_decl)) > kind = "consteval"; > + auto_diagnostic_group d; > error_at (DECL_SOURCE_LOCATION (new_decl), > "redeclaration %qD differs in %qs " > "from previous declaration", new_decl, > @@ -1567,6 +1568,7 @@ duplicate_function_template_decls (tree newdecl, tree olddecl) > if (template_heads_equivalent_p (newdecl, olddecl) > && function_requirements_equivalent_p (newres, oldres)) > { > + auto_diagnostic_group d; > error ("ambiguating new declaration %q+#D", newdecl); > inform (DECL_SOURCE_LOCATION (olddecl), > "old declaration %q#D", olddecl); > @@ -1902,6 +1904,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) > return NULL_TREE; > > /* There can only be one! */ > + auto_diagnostic_group d; > if (TREE_CODE (newdecl) == TEMPLATE_DECL > && check_raw_literal_operator (olddecl)) > error_at (newdecl_loc, > @@ -1924,6 +1927,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) > /* One is an implicit typedef, that's ok. */ > return NULL_TREE; > > + auto_diagnostic_group d; > error ("%q#D redeclared as different kind of entity", newdecl); > inform (olddecl_loc, "previous declaration %q#D", olddecl); > > @@ -1947,6 +1951,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) > if (TREE_CODE (oldres) == TYPE_DECL > || TREE_CODE (newres) == TYPE_DECL) > { > + auto_diagnostic_group d; > error_at (newdecl_loc, > "conflicting declaration of template %q#D", newdecl); > inform (olddecl_loc, > @@ -1967,6 +1972,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) > { > if (DECL_EXTERN_C_P (newdecl) && DECL_EXTERN_C_P (olddecl)) > { > + auto_diagnostic_group d; > error_at (newdecl_loc, > "conflicting declaration of C function %q#D", > newdecl); > @@ -1988,6 +1994,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) > // And the same constraints. > && equivalently_constrained (newdecl, olddecl)) > { > + auto_diagnostic_group d; > error_at (newdecl_loc, > "ambiguating new declaration of %q#D", newdecl); > inform (olddecl_loc, > @@ -1999,6 +2006,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) > } > else > { > + auto_diagnostic_group d; > error_at (newdecl_loc, "conflicting declaration %q#D", newdecl); > inform (olddecl_loc, > "previous declaration as %q#D", olddecl); > @@ -2010,6 +2018,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) > { > /* OMP UDRs are never duplicates. */ > gcc_assert (DECL_OMP_DECLARE_REDUCTION_P (olddecl)); > + auto_diagnostic_group d; > error_at (newdecl_loc, > "redeclaration of %<pragma omp declare reduction%>"); > inform (olddecl_loc, > @@ -2311,10 +2320,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) > { > if (merge_attr) > { > - if (diagnose_mismatched_attributes (olddecl, newdecl)) > - inform (olddecl_loc, DECL_INITIAL (olddecl) > - ? G_("previous definition of %qD here") > - : G_("previous declaration of %qD here"), olddecl); > + { > + auto_diagnostic_group d; > + if (diagnose_mismatched_attributes (olddecl, newdecl)) > + inform (olddecl_loc, DECL_INITIAL (olddecl) > + ? G_("previous definition of %qD here") > + : G_("previous declaration of %qD here"), olddecl); > + } > > /* [dcl.attr.noreturn]: The first declaration of a function shall > specify the noreturn attribute if any declaration of that function > @@ -2327,6 +2339,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) > && cxx11_attribute_p (a) > && get_attribute_namespace (a) == NULL_TREE) > { > + auto_diagnostic_group d; > error_at (newdecl_loc, "function %qD declared %<[[noreturn]]%> " > "but its first declaration was not", newdecl); > inform (olddecl_loc, "previous declaration of %qD", olddecl); > @@ -3597,6 +3610,7 @@ lookup_label_1 (tree id, bool making_local_p) > > if (old->binding_level == current_binding_level) > { > + auto_diagnostic_group d; > error ("local label %qE conflicts with existing label", id); > inform (DECL_SOURCE_LOCATION (old->label_decl), "previous label"); > return NULL; > @@ -3712,6 +3726,7 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, > bool exited_omp, const location_t *locus, > vec<tree,va_gc> *computed) > { > + auto_diagnostic_group d; > cp_binding_level *b; > bool complained = false; > int identified = 0; > @@ -3858,6 +3873,7 @@ check_switch_goto (cp_binding_level* level) > void > check_goto_1 (named_label_entry *ent, bool computed) > { > + auto_diagnostic_group d; > tree decl = ent->label_decl; > > /* If the label hasn't been defined yet, defer checking. */ > @@ -4531,6 +4547,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error ("lookup of %qT in %qT is ambiguous", name, context); > print_candidates (t); > } > @@ -4626,6 +4643,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error ("template parameters do not match template %qD", tmpl); > inform (DECL_SOURCE_LOCATION (tmpl), > "%qD declared here", tmpl); > @@ -5764,6 +5782,7 @@ check_tag_decl (cp_decl_specifier_seq *declspecs, > No attribute-specifier-seq shall appertain to an explicit > instantiation. */ > { > + auto_diagnostic_group d; > if (warning_at (loc, OPT_Wattributes, > "attribute ignored in explicit instantiation %q#T", > declared_type)) > @@ -5999,6 +6018,7 @@ start_decl (const cp_declarator *declarator, > /* OK, specialization was already checked. */; > else if (variable_template_p (field) && !this_tmpl) > { > + auto_diagnostic_group d; > error_at (DECL_SOURCE_LOCATION (decl), > "non-member-template declaration of %qD", decl); > inform (DECL_SOURCE_LOCATION (field), "does not match " > @@ -6661,6 +6681,7 @@ maybe_commonize_var (tree decl) > msg = G_("sorry: semantics of inline function " > "static data %q#D are wrong (you%'ll wind " > "up with multiple copies)"); > + auto_diagnostic_group d; > if (warning_at (DECL_SOURCE_LOCATION (decl), 0, > msg, decl)) > inform (DECL_SOURCE_LOCATION (decl), > @@ -6698,6 +6719,7 @@ check_for_uninitialized_const_var (tree decl, bool constexpr_context_p, > if (!field) > return true; > > + auto_diagnostic_group d; > bool show_notes = true; > > if (!constexpr_context_p || cxx_dialect >= cxx20) > @@ -7062,6 +7084,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p, > { > if (field && TREE_CODE (field) == TREE_LIST) > { > + auto_diagnostic_group g; > error ("request for member %qD is ambiguous", > d->cur->index); > print_candidates (field); > @@ -7884,6 +7907,7 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups) > { > static int explained = 0; > > + auto_diagnostic_group d; > if (cxx_dialect < cxx11) > error ("initializer invalid for static member with constructor"); > else if (cxx_dialect < cxx17) > @@ -8560,6 +8584,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, > && !type_uses_auto (type) > && !COMPLETE_TYPE_P (complete_type (type))) > { > + auto_diagnostic_group d; > error_at (location_of (decl), > "deduced type %qT for %qD is incomplete", type, decl); > cxx_incomplete_type_inform (type); > @@ -9059,6 +9084,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, > complete_type (TREE_TYPE (decl)); > if (!omp_mappable_type (TREE_TYPE (decl))) > { > + auto_diagnostic_group d; > error ("%q+D in declare target directive does not have mappable" > " type", decl); > if (TREE_TYPE (decl) != error_mark_node > @@ -9114,6 +9140,7 @@ find_decomp_class_base (location_t loc, tree type, tree ret) > return type; > else if (ANON_AGGR_TYPE_P (TREE_TYPE (field))) > { > + auto_diagnostic_group d; > if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE) > error_at (loc, "cannot decompose class type %qT because it has an " > "anonymous struct member", type); > @@ -9125,6 +9152,7 @@ find_decomp_class_base (location_t loc, tree type, tree ret) > } > else if (!accessible_p (type, field, true)) > { > + auto_diagnostic_group d; > error_at (loc, "cannot decompose inaccessible member %qD of %qT", > field, type); > inform (DECL_SOURCE_LOCATION (field), > @@ -9425,6 +9453,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp) > if (count != eltscnt) > { > cnt_mismatch: > + auto_diagnostic_group d; > if (count > eltscnt) > error_n (loc, count, > "%u name provided for structured binding", > @@ -9505,6 +9534,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp) > } > if (!tree_fits_uhwi_p (tsize)) > { > + auto_diagnostic_group d; > error_n (loc, count, > "%u name provided for structured binding", > "%u names provided for structured binding", count); > @@ -10096,6 +10126,7 @@ expand_static_init (tree decl, tree init) > if (CP_DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl) > && !DECL_FUNCTION_SCOPE_P (decl)) > { > + auto_diagnostic_group d; > location_t dloc = DECL_SOURCE_LOCATION (decl); > if (init) > error_at (dloc, "non-local variable %qD declared %<__thread%> " > @@ -10870,6 +10901,7 @@ grokfndecl (tree ctype, > if (in_namespace == NULL_TREE > && CP_DECL_CONTEXT (decl) != CP_TYPE_CONTEXT (type)) > { > + auto_diagnostic_group d; > error_at (location, "deduction guide %qD must be declared in the " > "same scope as %qT", decl, type); > inform (location_of (type), " declared here"); > @@ -10878,6 +10910,7 @@ grokfndecl (tree ctype, > if (DECL_CLASS_SCOPE_P (decl) > && current_access_specifier != declared_access (TYPE_NAME (type))) > { > + auto_diagnostic_group d; > error_at (location, "deduction guide %qD must have the same access " > "as %qT", decl, type); > inform (location_of (type), " declared here"); > @@ -10897,6 +10930,7 @@ grokfndecl (tree ctype, > /* [over.literal]/6: Literal operators shall not have C linkage. */ > if (DECL_LANGUAGE (decl) == lang_c) > { > + auto_diagnostic_group d; > error_at (location, "literal operator with C linkage"); > maybe_show_extern_c_location (); > return NULL_TREE; > @@ -11063,6 +11097,7 @@ grokfndecl (tree ctype, > } > else if (DECL_DEFAULTED_FN (old_decl)) > { > + auto_diagnostic_group d; > error ("definition of explicitly-defaulted %q+D", decl); > inform (DECL_SOURCE_LOCATION (old_decl), > "%q#D explicitly defaulted here", old_decl); > @@ -13219,6 +13254,7 @@ grokdeclarator (const cp_declarator *declarator, > && !diagnose_misapplied_contracts (declspecs->std_attributes)) > { > location_t attr_loc = declspecs->locations[ds_std_attribute]; > + auto_diagnostic_group d; > if (any_nonignored_attribute_p (declspecs->std_attributes) > && warning_at (attr_loc, OPT_Wattributes, "attribute ignored")) > inform (attr_loc, "an attribute that appertains to a type-specifier " > @@ -13290,6 +13326,7 @@ grokdeclarator (const cp_declarator *declarator, > && (MAYBE_CLASS_TYPE_P (type) > || TREE_CODE (type) == ENUMERAL_TYPE))) > { > + auto_diagnostic_group d; > if (warning_at (declarator->parenthesized, OPT_Wparentheses, > "unnecessary parentheses in declaration of %qs", > name)) > @@ -13450,6 +13487,7 @@ grokdeclarator (const cp_declarator *declarator, > /* OK for C++11 lambdas. */; > else if (cxx_dialect < cxx14) > { > + auto_diagnostic_group d; > error_at (typespec_loc, "%qs function uses " > "%<auto%> type specifier without " > "trailing return type", name); > @@ -13501,6 +13539,7 @@ grokdeclarator (const cp_declarator *declarator, > } > else if (!late_return_type) > { > + auto_diagnostic_group d; > error_at (declarator->id_loc, "deduction guide " > "for %qT must have trailing return " > "type", TREE_TYPE (tmpl)); > @@ -14737,6 +14776,7 @@ grokdeclarator (const cp_declarator *declarator, > tree tmpl = TREE_OPERAND (unqualified_id, 0); > if (variable_template_p (tmpl)) > { > + auto_diagnostic_group d; > error_at (id_loc, "specialization of variable template " > "%qD declared as function", tmpl); > inform (DECL_SOURCE_LOCATION (tmpl), > @@ -14803,6 +14843,7 @@ grokdeclarator (const cp_declarator *declarator, > { > if (unqualified_id) > { > + auto_diagnostic_group d; > error_at (id_loc, "field %qD has incomplete type %qT", > unqualified_id, type); > cxx_incomplete_type_inform (strip_array_types (type)); > @@ -14848,6 +14889,7 @@ grokdeclarator (const cp_declarator *declarator, > && !all_attributes_are_contracts_p (*attrlist)) > { > *attrlist = NULL_TREE; > + auto_diagnostic_group d; > if (warning_at (id_loc, OPT_Wattributes, "attribute ignored")) > inform (id_loc, "an attribute that appertains to a friend " > "declaration that is not a definition is ignored"); > @@ -16359,6 +16401,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, > && !DECL_SELF_REFERENCE_P (decl) > && tag_code != typename_type) > { > + auto_diagnostic_group d; > if (alias_template_specialization_p (type, nt_opaque)) > error ("using alias template specialization %qT after %qs", > type, tag_name (tag_code)); > @@ -16373,6 +16416,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, > && tag_code != enum_type > && tag_code != typename_type) > { > + auto_diagnostic_group d; > error ("%qT referred to as %qs", type, tag_name (tag_code)); > inform (location_of (type), "%qT has a previous declaration here", type); > return error_mark_node; > @@ -16380,6 +16424,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, > else if (TREE_CODE (type) != ENUMERAL_TYPE > && tag_code == enum_type) > { > + auto_diagnostic_group d; > error ("%qT referred to as enum", type); > inform (location_of (type), "%qT has a previous declaration here", type); > return error_mark_node; > @@ -16437,6 +16482,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, > > if (TREE_CODE (decl) == TREE_LIST) > { > + auto_diagnostic_group d; > error ("reference to %qD is ambiguous", name); > print_candidates (decl); > return error_mark_node; > @@ -16446,6 +16492,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, > && !template_header_p > && how == TAG_how::CURRENT_ONLY) > { > + auto_diagnostic_group d; > error ("class template %qD redeclared as non-template", name); > inform (location_of (decl), "previous declaration here"); > CLASSTYPE_ERRONEOUS (TREE_TYPE (decl)) = true; > @@ -16496,6 +16543,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, > && (!CLASSTYPE_TEMPLATE_INFO (t) > || (!PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))))) > { > + auto_diagnostic_group d; > error ("%qT is not a template", t); > inform (location_of (t), "previous declaration here"); > if (TYPE_CLASS_SCOPE_P (t) > @@ -16632,6 +16680,7 @@ xref_tag (enum tag_types tag_code, tree name, > && CLASS_TYPE_P (t) > && CLASSTYPE_IS_TEMPLATE (t)) > { > + auto_diagnostic_group d; > error ("redeclaration of %qT as a non-template", t); > inform (location_of (t), "previous declaration %qD", t); > return error_mark_node; > @@ -17623,6 +17672,7 @@ cxx_simulate_enum_decl (location_t loc, const char *name, > NULL_TREE, false, NULL); > if (!OPAQUE_ENUM_P (enumtype)) > { > + auto_diagnostic_group d; > error_at (loc, "multiple definition of %q#T", enumtype); > inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)), > "previous definition here"); > @@ -18679,6 +18729,7 @@ finish_function (bool inline_p) > else if (!current_function_returns_value > && !current_function_returns_null) > { > + auto_diagnostic_group d; > error ("no return statements in function returning %qT", > DECL_SAVED_AUTO_RETURN_TYPE (fndecl)); > inform (input_location, "only plain %<auto%> return type can be " > diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc > index c67e3e0c15f..3c4f34868ee 100644 > --- a/gcc/cp/decl2.cc > +++ b/gcc/cp/decl2.cc > @@ -911,6 +911,7 @@ check_classfn (tree ctype, tree function, tree template_parms) > if (DECL_CONV_FN_P (function)) > fns = get_class_binding (ctype, conv_op_identifier); > > + auto_diagnostic_group d; > error_at (DECL_SOURCE_LOCATION (function), > "no declaration matches %q#D", function); > if (fns) > @@ -5120,6 +5121,7 @@ record_mangling (tree decl, bool need_warning) > *slot = decl; > else if (need_warning) > { > + auto_diagnostic_group d; > error_at (DECL_SOURCE_LOCATION (decl), > "mangling of %q#D as %qE conflicts with a previous mangle", > decl, id); > @@ -6078,6 +6080,7 @@ mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */) > sorry ("converting lambda that uses %<...%> to function pointer"); > else if (complain & tf_error) > { > + auto_diagnostic_group d; > if (DECL_INITIAL (decl) > && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST) > { > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc > index 420fad26b7b..60d1e8bdb32 100644 > --- a/gcc/cp/error.cc > +++ b/gcc/cp/error.cc > @@ -4796,12 +4796,14 @@ qualified_name_lookup_error (tree scope, tree name, > scope); > else if (TREE_CODE (decl) == TREE_LIST) > { > + auto_diagnostic_group d; > error_at (location, "reference to %<%T::%D%> is ambiguous", > scope, name); > print_candidates (decl); > } > else > { > + auto_diagnostic_group d; > name_hint hint; > if (SCOPED_ENUM_P (scope) && TREE_CODE (name) == IDENTIFIER_NODE) > hint = suggest_alternative_in_scoped_enum (name, scope); > diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc > index 0231bd2507d..7b4abd1f56e 100644 > --- a/gcc/cp/except.cc > +++ b/gcc/cp/except.cc > @@ -736,6 +736,7 @@ build_throw (location_t loc, tree exp, tsubst_flags_t complain) > exp = moved; > > /* Call the copy constructor. */ > + auto_diagnostic_group d; > releasing_vec exp_vec (make_tree_vector_single (exp)); > exp = build_special_member_call (object, complete_ctor_identifier, > &exp_vec, TREE_TYPE (object), flags, > diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc > index 20373d26988..be7fdb40dd6 100644 > --- a/gcc/cp/init.cc > +++ b/gcc/cp/init.cc > @@ -662,6 +662,7 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain) > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error ("default member initializer for %qD required before the end " > "of its enclosing class", member); > inform (location_of (init), "defined here"); > @@ -2736,6 +2737,7 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, > ++ error_count; > if (complain) > { > + auto_diagnostic_group d; > if (DECL_CONTEXT (field) == origin) > { > if (using_new) > @@ -2764,6 +2766,7 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, > ++ error_count; > if (complain) > { > + auto_diagnostic_group d; > if (DECL_CONTEXT (field) == origin) > { > if (using_new) > @@ -2890,6 +2893,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper) > bool warned = false; > if (nelts) > nelts = fold_for_warn (nelts); > + > + auto_diagnostic_group d; > if (nelts) > if (CONSTANT_CLASS_P (nelts)) > warned = warning_at (loc, OPT_Wplacement_new_, > @@ -3408,6 +3413,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error ("request for member %qD is ambiguous", fnname); > print_candidates (fns); > } > @@ -4125,6 +4131,7 @@ build_vec_delete_1 (location_t loc, tree base, tree maxindex, tree type, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > int saved_errorcount = errorcount; > if (permerror_opt (loc, OPT_Wdelete_incomplete, > "operator %<delete []%> used on " > @@ -5209,6 +5216,7 @@ build_delete (location_t loc, tree otype, tree addr, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > int saved_errorcount = errorcount; > if (permerror_opt (loc, OPT_Wdelete_incomplete, > "operator %<delete%> used on " > diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc > index 0770417810e..e17c00217b2 100644 > --- a/gcc/cp/lambda.cc > +++ b/gcc/cp/lambda.cc > @@ -562,6 +562,7 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, > else if (!dependent_type_p (type) > && variably_modified_type_p (type, NULL_TREE)) > { > + auto_diagnostic_group d; > sorry ("capture of variably-modified type %qT that is not an N3639 array " > "of runtime bound", type); > if (TREE_CODE (type) == ARRAY_TYPE > @@ -600,6 +601,7 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, > type = complete_type (type); > if (!COMPLETE_TYPE_P (type)) > { > + auto_diagnostic_group d; > error ("capture by copy of incomplete type %qT", type); > cxx_incomplete_type_inform (type); > return error_mark_node; > @@ -757,6 +759,7 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) > && this_capture_p > && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_COPY) > { > + auto_diagnostic_group d; > if (warning_at (LAMBDA_EXPR_LOCATION (lambda), OPT_Wdeprecated, > "implicit capture of %qE via %<[=]%> is deprecated " > "in C++20", this_identifier)) > diff --git a/gcc/cp/lex.cc b/gcc/cp/lex.cc > index 1110db7f8d0..79d9490c4ad 100644 > --- a/gcc/cp/lex.cc > +++ b/gcc/cp/lex.cc > @@ -807,6 +807,7 @@ unqualified_fn_lookup_error (cp_expr name_expr) > Note that we have the exact wording of the following message in > the manual (trouble.texi, node "Name lookup"), so they need to > be kept in synch. */ > + auto_diagnostic_group d; > permerror (loc, "there are no arguments to %qD that depend on a template " > "parameter, so a declaration of %qD must be available", > name, name); > diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc > index 0b21656ed61..68a776d2c5a 100644 > --- a/gcc/cp/method.cc > +++ b/gcc/cp/method.cc > @@ -1787,6 +1787,7 @@ synthesize_method (tree fndecl) > int error_count = errorcount; > int warning_count = warningcount + werrorcount; > special_function_kind sfk = special_function_p (fndecl); > + auto_diagnostic_group d; > > /* Reset the source location, we might have been previously > deferred, and thus have saved where we were first needed. */ > @@ -3558,6 +3559,7 @@ defaulted_late_check (tree fn) > TREE_TYPE (TREE_TYPE (implicit_fn))) > || !compare_fn_params (fn, implicit_fn)) > { > + auto_diagnostic_group d; > error ("defaulted declaration %q+D does not match the " > "expected signature", fn); > inform (DECL_SOURCE_LOCATION (fn), > @@ -3593,6 +3595,7 @@ defaulted_late_check (tree fn) > { > if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) > { > + auto_diagnostic_group d; > error ("explicitly defaulted function %q+D cannot be declared " > "%qs because the implicit declaration is not %qs:", fn, > DECL_IMMEDIATE_FUNCTION_P (fn) ? "consteval" : "constexpr", > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > index 95c2405fcd4..647208944da 100644 > --- a/gcc/cp/module.cc > +++ b/gcc/cp/module.cc > @@ -11627,6 +11627,7 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef) > { > // FIXME:QOI Might be template specialization from a module, > // not necessarily global module > + auto_diagnostic_group d; > error_at (DECL_SOURCE_LOCATION (decl), > "conflicting global module declaration %#qD", decl); > inform (DECL_SOURCE_LOCATION (existing), > @@ -12682,6 +12683,7 @@ trees_in::read_enum_def (tree defn, tree maybe_template) > > if (known || values) > { > + auto_diagnostic_group d; > error_at (DECL_SOURCE_LOCATION (maybe_dup), > "definition of %qD does not match", maybe_dup); > inform (DECL_SOURCE_LOCATION (defn), > @@ -14497,6 +14499,7 @@ module_state::check_not_purview (location_t from) > if (imp == this) > { > /* Cannot import the current module. */ > + auto_diagnostic_group d; > error_at (from, "cannot import module in its own purview"); > inform (loc, "module %qs declared here", get_flatname ()); > return false; > @@ -17859,6 +17862,7 @@ module_state::deferred_macro (cpp_reader *reader, location_t loc, > { > /* If LOC is the first loc, this is the end of file check, which > is a warning. */ > + auto_diagnostic_group d; > if (loc == MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (line_table, 0))) > warning_at (loc, OPT_Winvalid_imported_macros, > "inconsistent imported macro definition %qE", > @@ -18133,6 +18137,7 @@ module_state::read_config (module_state_config &config) > > /* Reject when either is non-experimental or when experimental > major versions differ. */ > + auto_diagnostic_group d; > bool reject_p = ((!IS_EXPERIMENTAL (my_ver) > || !IS_EXPERIMENTAL (their_ver) > || MODULE_MAJOR (my_ver) != MODULE_MAJOR (their_ver)) > @@ -18945,6 +18950,7 @@ module_state::check_read (bool outermost, bool ok) > > if (int e = from ()->get_error ()) > { > + auto_diagnostic_group d; > error_at (loc, "failed to read compiled module: %s", > from ()->get_error (filename)); > note_cmi_name (); > @@ -19878,6 +19884,7 @@ declare_module (module_state *module, location_t from_loc, bool exporting_p, > module_state *current = (*modules)[0]; > if (module_purview_p () || module->loadedness > ML_CONFIG) > { > + auto_diagnostic_group d; > error_at (from_loc, module_purview_p () > ? G_("module already declared") > : G_("module already imported")); > @@ -20535,6 +20542,7 @@ init_modules (cpp_reader *reader) > || (cpp_opts->deps.style != DEPS_NONE > && !cpp_opts->deps.need_preprocessor_output)) > { > + auto_diagnostic_group d; > warning (0, flag_dump_macros == 'M' > ? G_("macro debug output may be incomplete with modules") > : G_("module dependencies require preprocessing")); > diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc > index 70ad4cbf3b5..7a6cc244c15 100644 > --- a/gcc/cp/name-lookup.cc > +++ b/gcc/cp/name-lookup.cc > @@ -2893,6 +2893,7 @@ supplement_binding (cxx_binding *binding, tree decl) > void > diagnose_name_conflict (tree decl, tree bval) > { > + auto_diagnostic_group d; > if (TREE_CODE (decl) == TREE_CODE (bval) > && TREE_CODE (decl) != NAMESPACE_DECL > && !DECL_DECLARES_FUNCTION_P (decl) > @@ -6213,6 +6214,7 @@ lookup_using_decl (tree scope, name_lookup &lookup) > /* We can (independently) have ambiguous implicit typedefs. */ > || (lookup.type && TREE_CODE (lookup.type) == TREE_LIST)) > { > + auto_diagnostic_group d; > error ("reference to %qD is ambiguous", lookup.name); > print_candidates (TREE_CODE (lookup.value) == TREE_LIST > ? lookup.value : lookup.type); > @@ -6344,6 +6346,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp) > if (TREE_CODE (old) == TREE_LIST) > { > ambiguous: > + auto_diagnostic_group d; > DECL_CONTEXT (decl) = FROB_CONTEXT (scope); > error ("reference to %qD is ambiguous", decl); > print_candidates (old); > @@ -6443,6 +6446,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp) > { > if (hidden_p) > { > + auto_diagnostic_group d; > pedwarn (DECL_SOURCE_LOCATION (decl), 0, > "%qD has not been declared within %qD", decl, scope); > inform (DECL_SOURCE_LOCATION (found), > @@ -8927,6 +8931,7 @@ finish_using_directive (tree target, tree attribs) > if (current_binding_level->kind == sk_namespace > && is_attribute_p ("strong", name)) > { > + auto_diagnostic_group d; > if (warning (0, "%<strong%> using directive no longer supported") > && CP_DECL_CONTEXT (target) == current_namespace) > inform (DECL_SOURCE_LOCATION (target), > @@ -9246,6 +9251,7 @@ push_namespace (tree name, bool make_inline) > > if (make_inline && !DECL_NAMESPACE_INLINE_P (ns)) > { > + auto_diagnostic_group d; > error_at (input_location, > "inline namespace must be specified at initial definition"); > inform (DECL_SOURCE_LOCATION (ns), "%qD defined here", ns); > @@ -9296,6 +9302,7 @@ add_imported_namespace (tree ctx, tree name, location_t loc, unsigned import, > } > else if (DECL_NAMESPACE_INLINE_P (decl) != inline_p) > { > + auto_diagnostic_group d; > error_at (loc, "%s namespace %qD conflicts with reachable definition", > inline_p ? "inline" : "non-inline", decl); > inform (DECL_SOURCE_LOCATION (decl), "reachable %s definition here", > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc > index edfa5a49440..8391ce431f3 100644 > --- a/gcc/cp/parser.cc > +++ b/gcc/cp/parser.cc > @@ -3504,6 +3504,7 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator, > if (declarator > && declarator->kind == cdk_function) > { > + auto_diagnostic_group d; > error_at (type_location, > "new types may not be defined in a return type"); > inform (type_location, > @@ -5086,24 +5087,27 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) > } > } > > - bool complained > - = emit_diagnostic (kind, input_location, opt, > - "unable to find numeric literal operator %qD", name); > - > - if (!complained) > - /* Don't inform either. */; > - else if (i14) > - { > - inform (token->location, "add %<using namespace std::complex_literals%> " > - "(from %<<complex>%>) to enable the C++14 user-defined literal " > - "suffixes"); > - if (ext) > - inform (token->location, "or use %<j%> instead of %<i%> for the " > - "GNU built-in suffix"); > - } > - else if (!ext) > - inform (token->location, "use %<-fext-numeric-literals%> " > - "to enable more built-in suffixes"); > + { > + auto_diagnostic_group d; > + bool complained > + = emit_diagnostic (kind, input_location, opt, > + "unable to find numeric literal operator %qD", name); > + > + if (!complained) > + /* Don't inform either. */; > + else if (i14) > + { > + inform (token->location, "add %<using namespace std::complex_literals%> " > + "(from %<<complex>%>) to enable the C++14 user-defined literal " > + "suffixes"); > + if (ext) > + inform (token->location, "or use %<j%> instead of %<i%> for the " > + "GNU built-in suffix"); > + } > + else if (!ext) > + inform (token->location, "use %<-fext-numeric-literals%> " > + "to enable more built-in suffixes"); > + } > > if (kind == DK_ERROR) > value = error_mark_node; > @@ -7159,6 +7163,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, > if (TREE_CODE (tid) == TEMPLATE_ID_EXPR > && TREE_CODE (TREE_OPERAND (tid, 0)) != IDENTIFIER_NODE) > { > + auto_diagnostic_group d; > tree tmpl = NULL_TREE; > if (is_overloaded_fn (tid)) > { > @@ -9641,10 +9646,13 @@ cp_parser_new_expression (cp_parser* parser) > message for this case. */ > if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)) > { > - error_at (token->location, > - "array bound forbidden after parenthesized type-id"); > - inform (token->location, > - "try removing the parentheses around the type-id"); > + { > + auto_diagnostic_group d; > + error_at (token->location, > + "array bound forbidden after parenthesized type-id"); > + inform (token->location, > + "try removing the parentheses around the type-id"); > + } > cp_parser_direct_new_declarator (parser); > } > } > @@ -10450,6 +10458,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, > && token->type == CPP_RSHIFT > && !parser->greater_than_is_operator_p) > { > + auto_diagnostic_group d; > if (warning_at (token->location, OPT_Wc__11_compat, > "%<>>%> operator is treated" > " as two right angle brackets in C++11")) > @@ -11724,6 +11733,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) > else if (!VAR_P (capture_init_expr) > && TREE_CODE (capture_init_expr) != PARM_DECL) > { > + auto_diagnostic_group d; > error_at (capture_token->location, > "capture of non-variable %qE", > capture_init_expr); > @@ -11735,6 +11745,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) > if (VAR_P (capture_init_expr) > && decl_storage_duration (capture_init_expr) != dk_auto) > { > + auto_diagnostic_group d; > if (pedwarn (capture_token->location, 0, "capture of variable " > "%qD with non-automatic storage duration", > capture_init_expr)) > @@ -15238,6 +15249,7 @@ cp_parser_module_declaration (cp_parser *parser, module_parse mp_state, > } > else if (scope != global_namespace) > { > + auto_diagnostic_group d; > error_at (token->location, "module-declaration must be at global scope"); > inform (DECL_SOURCE_LOCATION (scope), "scope opened here"); > goto skip_eol; > @@ -15315,19 +15327,22 @@ cp_parser_import_declaration (cp_parser *parser, module_parse mp_state, > > if (mp_state == MP_PURVIEW || mp_state == MP_PRIVATE) > { > + auto_diagnostic_group d; > error_at (token->location, "post-module-declaration" > " imports must be contiguous"); > - note_lexer: > inform (token->location, "perhaps insert a line break after" > " %<import%>, or other disambiguation, to prevent this" > " being considered a module control-line"); > - skip_eol: > cp_parser_skip_to_pragma_eol (parser, token); > } > else if (current_scope () != global_namespace) > { > + auto_diagnostic_group d; > error_at (token->location, "import-declaration must be at global scope"); > - goto note_lexer; > + inform (token->location, "perhaps insert a line break after" > + " %<import%>, or other disambiguation, to prevent this" > + " being considered a module control-line"); > + cp_parser_skip_to_pragma_eol (parser, token); > } > else > { > @@ -15355,7 +15370,10 @@ cp_parser_import_declaration (cp_parser *parser, module_parse mp_state, > tree attrs = cp_parser_attributes_opt (parser); > > if (!mod || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)) > - goto skip_eol; > + { > + cp_parser_skip_to_pragma_eol (parser, token); > + return; > + } > cp_parser_require_pragma_eol (parser, token); > > if (mp_state == MP_PURVIEW_IMPORTS || mp_state == MP_PRIVATE_IMPORTS) > @@ -15648,6 +15666,7 @@ cp_parser_declaration (cp_parser* parser, tree prefix_attrs) > if (!c_dialect_objc ()) > { > location_t where = get_finish (t2->location); > + auto_diagnostic_group d; > warning_at (token1->location, OPT_Wattributes, "attributes are" > " not permitted in this position"); > where = linemap_position_for_loc_and_offset (line_table, > @@ -16899,6 +16918,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, > > if (decl_specs->std_attributes) > { > + auto_diagnostic_group d; > error_at (decl_specs->locations[ds_std_attribute], > "standard attributes in middle of decl-specifiers"); > inform (decl_specs->locations[ds_std_attribute], > @@ -19148,6 +19168,7 @@ cp_parser_template_id (cp_parser *parser, > } > /* Otherwise, emit an error about the invalid digraph, but continue > parsing because we got our argument list. */ > + auto_diagnostic_group d; > if (permerror (next_token->location, > "%<<::%> cannot begin a template-argument list")) > { > @@ -19187,6 +19208,7 @@ cp_parser_template_id (cp_parser *parser, > /* C++20 says that "function-name < a;" is now ill-formed. */ > if (cp_parser_error_occurred (parser)) > { > + auto_diagnostic_group d; > error_at (token->location, "invalid template-argument-list"); > inform (token->location, "function name as the left hand " > "operand of %<<%> is ill-formed in C++20; wrap the " > @@ -19432,10 +19454,13 @@ cp_parser_template_name (cp_parser* parser, > cp_token_position start = 0; > > /* Explain what went wrong. */ > - error_at (token->location, "non-template %qD used as template", > - identifier); > - inform (token->location, "use %<%T::template %D%> to indicate that it is a template", > - parser->scope, identifier); > + { > + auto_diagnostic_group d; > + error_at (token->location, "non-template %qD used as template", > + identifier); > + inform (token->location, "use %<%T::template %D%> to indicate " > + "that it is a template", parser->scope, identifier); > + } > /* If parsing tentatively, find the location of the "<" token. */ > if (cp_parser_simulate_error (parser)) > start = cp_lexer_token_position (parser->lexer, true); > @@ -20103,6 +20128,7 @@ cp_parser_explicit_specialization (cp_parser* parser) > bool need_lang_pop = current_lang_name == lang_name_c; > if (need_lang_pop) > { > + auto_diagnostic_group d; > error_at (token->location, "template specialization with C linkage"); > maybe_show_extern_c_location (); > > @@ -20935,6 +20961,7 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, > { > if (!tentative) > { > + auto_diagnostic_group d; > error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); > inform (DECL_SOURCE_LOCATION (con), "concept defined here"); > } > @@ -21548,6 +21575,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, > "attributes ignored on template instantiation"); > else if (is_friend && cxx11_attribute_p (attributes)) > { > + auto_diagnostic_group d; > if (warning (OPT_Wattributes, "attribute ignored")) > inform (input_location, "an attribute that appertains to a friend " > "declaration that is not a definition is ignored"); > @@ -21900,6 +21928,7 @@ cp_parser_enum_specifier (cp_parser* parser) > } > else > { > + auto_diagnostic_group d; > error_at (type_start_token->location, > "multiple definition of %q#T", type); > inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)), > @@ -22947,6 +22976,7 @@ cp_parser_asm_definition (cp_parser* parser) > case RID_VOLATILE: > if (volatile_loc) > { > + auto_diagnostic_group d; > error_at (loc, "duplicate %<asm%> qualifier %qT", > token->u.value); > inform (volatile_loc, "first seen here"); > @@ -22964,6 +22994,7 @@ cp_parser_asm_definition (cp_parser* parser) > case RID_INLINE: > if (inline_loc) > { > + auto_diagnostic_group d; > error_at (loc, "duplicate %<asm%> qualifier %qT", > token->u.value); > inform (inline_loc, "first seen here"); > @@ -22978,6 +23009,7 @@ cp_parser_asm_definition (cp_parser* parser) > case RID_GOTO: > if (goto_loc) > { > + auto_diagnostic_group d; > error_at (loc, "duplicate %<asm%> qualifier %qT", > token->u.value); > inform (goto_loc, "first seen here"); > @@ -23791,12 +23823,13 @@ cp_parser_init_declarator (cp_parser* parser, > attributes -- but ignores them. Made a permerror in GCC 8. */ > if (cp_parser_allow_gnu_extensions_p (parser) > && initialization_kind == CPP_OPEN_PAREN > - && cp_parser_attributes_opt (parser) > - && permerror (input_location, > - "attributes after parenthesized initializer ignored")) > + && cp_parser_attributes_opt (parser)) > { > static bool hint; > - if (flag_permissive && !hint) > + auto_diagnostic_group d; > + if (permerror (input_location, > + "attributes after parenthesized initializer ignored") > + && flag_permissive && !hint) > { > hint = true; > inform (input_location, > @@ -24496,6 +24529,7 @@ cp_parser_direct_declarator (cp_parser* parser, > else if (qualifying_scope > && CLASSTYPE_USE_TEMPLATE (name_type)) > { > + auto_diagnostic_group d; > error_at (declarator_id_start_token->location, > "invalid use of constructor as a template"); > inform (declarator_id_start_token->location, > @@ -27890,6 +27924,7 @@ cp_parser_class_head (cp_parser* parser, > if (type != error_mark_node > && (COMPLETE_TYPE_P (type) || TYPE_BEING_DEFINED (type))) > { > + auto_diagnostic_group d; > error_at (type_start_token->location, "redefinition of %q#T", > type); > inform (location_of (type), "previous definition of %q#T", > @@ -28344,6 +28379,7 @@ cp_parser_member_declaration (cp_parser* parser) > && cxx11_attribute_p (decl_specifiers.attributes)) > { > decl_specifiers.attributes = NULL_TREE; > + auto_diagnostic_group d; > if (warning_at (decl_spec_token_start->location, > OPT_Wattributes, "attribute ignored")) > inform (decl_spec_token_start->location, "an attribute " > @@ -32449,6 +32485,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, > cp_parser_error, so we incorporate its actions directly. */ > if (!cp_parser_simulate_error (parser)) > { > + auto_diagnostic_group d; > error_at (name_location, "reference to %qD is ambiguous", > name); > print_candidates (decl); > @@ -33260,6 +33297,7 @@ cp_parser_explicit_template_declaration (cp_parser* parser, bool member_p) > A template ... shall not have C linkage. */ > if (current_lang_name == lang_name_c) > { > + auto_diagnostic_group d; > error_at (location, "template with C linkage"); > maybe_show_extern_c_location (); > /* Give it C++ linkage to avoid confusing other parts of the > @@ -35236,6 +35274,7 @@ cp_parser_check_class_key (cp_parser *parser, location_t key_loc, > bool seen_as_union = TREE_CODE (type) == UNION_TYPE; > if (seen_as_union != (class_key == union_type)) > { > + auto_diagnostic_group d; > if (permerror (input_location, "%qs tag used in naming %q#T", > class_key == union_type ? "union" > : class_key == record_type ? "struct" : "class", > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 024fa8a5529..f60b1069d6d 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -1124,6 +1124,7 @@ maybe_process_partial_specialization (tree type) > if (current_namespace > != decl_namespace_context (tmpl)) > { > + auto_diagnostic_group d; > if (permerror (input_location, > "specialization of %qD in different namespace", > type)) > @@ -2471,6 +2472,7 @@ determine_specialization (tree template_id, > > if (templates == NULL_TREE && candidates == NULL_TREE) > { > + auto_diagnostic_group d; > error ("template-id %qD for %q+D does not match any template " > "declaration", template_id, decl); > if (header_mismatch) > @@ -2485,6 +2487,7 @@ determine_specialization (tree template_id, > || (candidates && TREE_CHAIN (candidates)) > || (templates && candidates)) > { > + auto_diagnostic_group d; > error ("ambiguous template specialization %qD for %q+D", > template_id, decl); > candidates = chainon (candidates, templates); > @@ -4311,6 +4314,7 @@ check_for_bare_parameter_packs (tree t, location_t loc /* = UNKNOWN_LOCATION */) > > if (parameter_packs) > { > + auto_diagnostic_group d; > error_at (loc, "parameter packs not expanded with %<...%>:"); > while (parameter_packs) > { > @@ -4455,6 +4459,7 @@ check_template_shadow (tree decl) > if (DECL_SELF_REFERENCE_P (decl)) > return false; > > + auto_diagnostic_group d; > if (DECL_TEMPLATE_PARM_P (decl)) > error ("declaration of template parameter %q+D shadows " > "template parameter", decl); > @@ -5141,7 +5146,6 @@ process_partial_specialization (tree decl) > int nargs = TREE_VEC_LENGTH (inner_args); > int ntparms; > int i; > - bool did_error_intro = false; > struct template_parm_data tpd; > struct template_parm_data tpd2; > > @@ -5195,24 +5199,29 @@ process_partial_specialization (tree decl) > NULL, > /*include_nondeduced_p=*/false); > } > - for (i = 0; i < ntparms; ++i) > - if (tpd.parms[i] == 0) > - { > - /* One of the template parms was not used in a deduced context in the > - specialization. */ > - if (!did_error_intro) > - { > - error ("template parameters not deducible in " > - "partial specialization:"); > - did_error_intro = true; > - } > > - inform (input_location, " %qD", > - TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); > - } > + { > + auto_diagnostic_group d; > + bool did_error_intro = false; > + for (i = 0; i < ntparms; ++i) > + if (tpd.parms[i] == 0) > + { > + /* One of the template parms was not used in a deduced context in the > + specialization. */ > + if (!did_error_intro) > + { > + error ("template parameters not deducible in " > + "partial specialization:"); > + did_error_intro = true; > + } > > - if (did_error_intro) > - return error_mark_node; > + inform (input_location, " %qD", > + TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); > + } > + > + if (did_error_intro) > + return error_mark_node; > + } > > /* [temp.class.spec] > > @@ -5224,6 +5233,7 @@ process_partial_specialization (tree decl) > && (!flag_concepts > || !strictly_subsumes (current_template_constraints (), maintmpl))) > { > + auto_diagnostic_group d; > if (!flag_concepts) > error ("partial specialization %q+D does not specialize " > "any template arguments; to define the primary template, " > @@ -5241,6 +5251,7 @@ process_partial_specialization (tree decl) > parameters. */ > if (nargs < DECL_NTPARMS (maintmpl)) > { > + auto_diagnostic_group d; > error ("partial specialization is not more specialized than the " > "primary template because it replaces multiple parameters " > "with a pack expansion"); > @@ -5251,6 +5262,7 @@ process_partial_specialization (tree decl) > > else if (nargs > DECL_NTPARMS (maintmpl)) > { > + auto_diagnostic_group d; > error ("too many arguments for partial specialization %qT", type); > inform (DECL_SOURCE_LOCATION (maintmpl), "primary template here"); > /* Avoid crash below. */ > @@ -6141,6 +6153,7 @@ push_template_decl (tree decl, bool is_friend) > (TI_ARGS (tinfo), > TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl))))) > { > + auto_diagnostic_group d; > error ("template arguments to %qD do not match original " > "template %qD", decl, DECL_TEMPLATE_RESULT (tmpl)); > if (!uses_template_parms (TI_ARGS (tinfo))) > @@ -6346,6 +6359,7 @@ redeclare_class_template (tree type, tree parms, tree cons) > > if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms)) > { > + auto_diagnostic_group d; > error_n (input_location, TREE_VEC_LENGTH (parms), > "redeclared with %d template parameter", > "redeclared with %d template parameters", > @@ -6862,6 +6876,7 @@ convert_nontype_argument_function (tree type, tree expr, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > location_t loc = cp_expr_loc_or_input_loc (expr); > error_at (loc, "%qE is not a valid template argument for type %qT", > expr, type); > @@ -6932,6 +6947,7 @@ check_valid_ptrmem_cst_expr (tree type, tree expr, > return true; > if (complain & tf_error) > { > + auto_diagnostic_group d; > location_t loc = cp_expr_loc_or_input_loc (orig_expr); > error_at (loc, "%qE is not a valid template argument for type %qT", > orig_expr, type); > @@ -7805,6 +7821,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error ("%qE is not a valid template argument for type %qT " > "because it is a pointer", expr, type); > inform (input_location, "try using %qE instead", > @@ -8663,6 +8680,7 @@ convert_template_argument (tree parm, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error ("type/value mismatch at argument %d in template " > "parameter list for %qD", > i + 1, in_decl); > @@ -8697,6 +8715,7 @@ convert_template_argument (tree parm, > { > if (in_decl && (complain & tf_error)) > { > + auto_diagnostic_group d; > error ("type/value mismatch at argument %d in template " > "parameter list for %qD", > i + 1, in_decl); > @@ -8747,6 +8766,7 @@ convert_template_argument (tree parm, > { > if (in_decl && (complain & tf_error)) > { > + auto_diagnostic_group d; > error ("type/value mismatch at argument %d in " > "template parameter list for %qD", > i + 1, in_decl); > @@ -8765,6 +8785,7 @@ convert_template_argument (tree parm, > { > if (in_decl && (complain & tf_error)) > { > + auto_diagnostic_group d; > error ("constraint mismatch at argument %d in " > "template parameter list for %qD", > i + 1, in_decl); > @@ -9147,6 +9168,7 @@ coerce_template_parms (tree parms, > bad_nargs: > if (complain & tf_error) > { > + auto_diagnostic_group d; > if (variadic_p || default_p) > { > nparms -= variadic_p + default_p; > @@ -9182,6 +9204,7 @@ coerce_template_parms (tree parms, > if (PACK_EXPANSION_P (arg) > && !template_parameter_pack_p (parm)) > { > + auto_diagnostic_group d; > if (DECL_ALIAS_TEMPLATE_P (in_decl)) > error_at (location_of (arg), > "pack expansion argument for non-pack parameter " > @@ -17373,6 +17396,7 @@ tsubst_qualified_id (tree qualified_id, tree args, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error ("dependent-name %qE is parsed as a non-type, but " > "instantiation yields a type", qualified_id); > inform (input_location, "say %<typename %E%> if a type is meant", qualified_id); > @@ -20965,6 +20989,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) > > if (unq != function) > { > + auto_diagnostic_group d; > char const *const msg > = G_("%qD was not declared in this scope, " > "and no declarations were found by " > @@ -26400,6 +26425,7 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain, > char *spaces = NULL; > if (!(complain & tf_error)) > return error_mark_node; > + auto_diagnostic_group d; > if (TYPE_P (target)) > error ("ambiguous template instantiation for %q#T", target); > else > @@ -30866,6 +30892,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, > { > /* Be permissive with equivalent alias templates. */ > tree u = get_underlying_template (tmpl); > + auto_diagnostic_group d; > diagnostic_t dk = (u == tmpl) ? DK_ERROR : DK_PEDWARN; > bool complained > = emit_diagnostic (dk, input_location, 0, > @@ -31022,6 +31049,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, > { > if (complain & tf_warning_or_error) > { > + auto_diagnostic_group d; > error ("class template argument deduction failed:"); > perform_dguide_overload_resolution (cands, args, complain); > if (elided) > @@ -31039,6 +31067,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, > if (complain & tf_warning_or_error) > { > // TODO: Pass down location from cp_finish_decl. > + auto_diagnostic_group d; > error ("class template argument deduction for %qT failed: " > "explicit deduction guide selected in " > "copy-list-initialization", type); > @@ -31054,6 +31083,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, > guides, this deduction might not be what the user intended. */ > if (fndecl != error_mark_node && !any_dguides_p && (complain & tf_warning)) > { > + auto_diagnostic_group d; > if ((!DECL_IN_SYSTEM_HEADER (fndecl) > || global_dc->m_warn_system_headers) > && warning (OPT_Wctad_maybe_unsupported, > @@ -31181,6 +31211,7 @@ do_auto_deduction (tree type, tree init, tree auto_node, > { > if (complain & tf_warning_or_error) > { > + auto_diagnostic_group d; > if (permerror (loc, "direct-list-initialization of " > "%<auto%> requires exactly one element")) > inform (loc, > diff --git a/gcc/cp/search.cc b/gcc/cp/search.cc > index 827f48e8604..60c30ecb881 100644 > --- a/gcc/cp/search.cc > +++ b/gcc/cp/search.cc > @@ -1227,6 +1227,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error ("request for member %qD is ambiguous", name); > print_candidates (lfi.ambiguous); > } > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc > index 5ab2076b673..3e117c216da 100644 > --- a/gcc/cp/semantics.cc > +++ b/gcc/cp/semantics.cc > @@ -2383,6 +2383,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > if (current_function_decl > && DECL_STATIC_FUNCTION_P (current_function_decl)) > error ("invalid use of member %qD in static member function", decl); > @@ -4248,6 +4249,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use) > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error ("%qD is not captured", decl); > tree closure = LAMBDA_EXPR_CLOSURE (lambda_expr); > if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE) > @@ -4268,6 +4270,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use) > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error (VAR_P (decl) > ? G_("use of local variable with automatic storage from " > "containing function") > @@ -4503,6 +4506,7 @@ finish_id_expression_1 (tree id_expression, > if (TREE_CODE (decl) == TREE_LIST) > { > /* Ambiguous reference to base members. */ > + auto_diagnostic_group d; > error ("request for member %qD is ambiguous in " > "multiple inheritance lattice", id_expression); > print_candidates (decl); > @@ -4909,6 +4913,7 @@ finish_offsetof (tree object_ptr, tree expr, location_t loc) > > if (DECL_P (expr)) > { > + auto_diagnostic_group d; > error ("cannot apply %<offsetof%> to member function %qD", expr); > inform (DECL_SOURCE_LOCATION (expr), "declared here"); > } > @@ -6321,6 +6326,7 @@ omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp, > return ret; > if (!ambiguous.is_empty ()) > { > + auto_diagnostic_group d; > const char *str = _("candidates are:"); > unsigned int idx; > tree udr; > @@ -8393,6 +8399,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) > && !type_dependent_expression_p (t) > && !omp_mappable_type (TREE_TYPE (t))) > { > + auto_diagnostic_group d; > error_at (OMP_CLAUSE_LOCATION (c), > "array section does not have mappable type " > "in %qs clause", > @@ -8615,6 +8622,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) > ? TREE_TYPE (TREE_TYPE (t)) > : TREE_TYPE (t))) > { > + auto_diagnostic_group d; > error_at (OMP_CLAUSE_LOCATION (c), > "%qD does not have a mappable type in %qs clause", t, > omp_clause_code_name[OMP_CLAUSE_CODE (c)]); > @@ -8782,6 +8790,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) > } > else if (!omp_mappable_type (TREE_TYPE (t))) > { > + auto_diagnostic_group d; > error_at (OMP_CLAUSE_LOCATION (c), > "%qD does not have a mappable type in %qs clause", t, > cname); > diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc > index 31ecbb1ac79..c3a38de4f48 100644 > --- a/gcc/cp/tree.cc > +++ b/gcc/cp/tree.cc > @@ -5223,6 +5223,7 @@ check_abi_tag_redeclaration (const_tree decl, const_tree old, const_tree new_) > if (new_ && TREE_CODE (TREE_VALUE (new_)) == TREE_LIST) > new_ = TREE_VALUE (new_); > bool err = false; > + auto_diagnostic_group d; > for (const_tree t = new_; t; t = TREE_CHAIN (t)) > { > tree str = TREE_VALUE (t); > @@ -5276,6 +5277,7 @@ check_abi_tag_args (tree args, tree name) > { > if (!ISALPHA (c) && c != '_') > { > + auto_diagnostic_group d; > error ("arguments to the %qE attribute must contain valid " > "identifiers", name); > inform (input_location, "%<%c%> is not a valid first " > @@ -5289,6 +5291,7 @@ check_abi_tag_args (tree args, tree name) > { > if (!ISALNUM (c) && c != '_') > { > + auto_diagnostic_group d; > error ("arguments to the %qE attribute must contain valid " > "identifiers", name); > inform (input_location, "%<%c%> is not a valid character " > diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc > index f26b5b2a1f4..e4e260645f6 100644 > --- a/gcc/cp/typeck.cc > +++ b/gcc/cp/typeck.cc > @@ -2365,6 +2365,7 @@ invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain) > { > if (DECL_P (expr)) > { > + auto_diagnostic_group d; > error_at (loc, "invalid use of non-static member function %qD", > expr); > inform (DECL_SOURCE_LOCATION (expr), "declared here"); > @@ -3309,6 +3310,7 @@ complain_about_unrecognized_member (tree access_path, tree name, > { > /* The guessed name isn't directly accessible, and no accessor > member function could be found. */ > + auto_diagnostic_group d; > error_at (&rich_loc, > "%q#T has no member named %qE;" > " did you mean %q#D? (not accessible from this context)", > @@ -3534,21 +3536,24 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, > else > { > /* Look up the member. */ > - access_failure_info afi; > - if (processing_template_decl) > - /* Even though this class member access expression is at this > - point not dependent, the member itself may be dependent, and > - we must not potentially push a access check for a dependent > - member onto TI_DEFERRED_ACCESS_CHECKS. So don't check access > - ahead of time here; we're going to redo this member lookup at > - instantiation time anyway. */ > - push_deferring_access_checks (dk_no_check); > - member = lookup_member (access_path, name, /*protect=*/1, > - /*want_type=*/false, complain, > - &afi); > - if (processing_template_decl) > - pop_deferring_access_checks (); > - afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); > + { > + auto_diagnostic_group d; > + access_failure_info afi; > + if (processing_template_decl) > + /* Even though this class member access expression is at this > + point not dependent, the member itself may be dependent, and > + we must not potentially push a access check for a dependent > + member onto TI_DEFERRED_ACCESS_CHECKS. So don't check access > + ahead of time here; we're going to redo this member lookup at > + instantiation time anyway. */ > + push_deferring_access_checks (dk_no_check); > + member = lookup_member (access_path, name, /*protect=*/1, > + /*want_type=*/false, complain, > + &afi); > + if (processing_template_decl) > + pop_deferring_access_checks (); > + afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); > + } > if (member == NULL_TREE) > { > if (dependentish_scope_p (object_type)) > @@ -4504,6 +4509,7 @@ error_args_num (location_t loc, tree fndecl, bool too_many_p) > { > if (fndecl) > { > + auto_diagnostic_group d; > if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE) > { > if (DECL_NAME (fndecl) == NULL_TREE > @@ -4952,6 +4958,7 @@ warn_for_null_address (location_t location, tree op, tsubst_flags_t complain) > STRIP_NOPS (cop); > } > > + auto_diagnostic_group d; > bool warned = false; > if (TREE_CODE (cop) == ADDR_EXPR) > { > @@ -6106,6 +6113,7 @@ cp_build_binary_op (const op_location_t &location, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error_at (location, "comparing vectors with different " > "element types"); > inform (location, "operand types are %qT and %qT", > @@ -6119,6 +6127,7 @@ cp_build_binary_op (const op_location_t &location, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error_at (location, "comparing vectors with different " > "number of elements"); > inform (location, "operand types are %qT and %qT", > @@ -6964,6 +6973,7 @@ build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > error_at (loc, "invalid use of %qE to form a " > "pointer-to-member-function", xarg.get_value ()); > if (TREE_CODE (xarg) != OFFSET_REF) > @@ -7498,10 +7508,13 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert, > { > /* Warn if the expression has boolean value. */ > if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE > - && (complain & tf_warning) > - && warning_at (location, OPT_Wbool_operation, > - "%<~%> on an expression of type %<bool%>")) > - inform (location, "did you mean to use logical not (%<!%>)?"); > + && (complain & tf_warning)) > + { > + auto_diagnostic_group d; > + if (warning_at (location, OPT_Wbool_operation, > + "%<~%> on an expression of type %<bool%>")) > + inform (location, "did you mean to use logical not (%<!%>)?"); > + } > arg = cp_perform_integral_promotions (arg, complain); > } > else if (!noconvert && VECTOR_TYPE_P (TREE_TYPE (arg))) > @@ -8723,6 +8736,7 @@ build_static_cast (location_t loc, tree type, tree oexpr, > > if (complain & tf_error) > { > + auto_diagnostic_group d; > error_at (loc, "invalid %<static_cast%> from type %qT to type %qT", > TREE_TYPE (expr), type); > if ((TYPE_PTR_P (type) || TYPE_REF_P (type)) > @@ -9682,15 +9696,19 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, > rhs = decay_conversion (rhs, complain); > if (rhs == error_mark_node) > return error_mark_node; > - rhs = stabilize_expr (rhs, &init); > - newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain); > - if (newrhs == error_mark_node) > - { > - if (complain & tf_error) > - inform (loc, " in evaluation of %<%Q(%#T, %#T)%>", > - modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs)); > - return error_mark_node; > - } > + > + { > + auto_diagnostic_group d; > + rhs = stabilize_expr (rhs, &init); > + newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain); > + if (newrhs == error_mark_node) > + { > + if (complain & tf_error) > + inform (loc, " in evaluation of %<%Q(%#T, %#T)%>", > + modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs)); > + return error_mark_node; > + } > + } > > if (init) > newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs); > @@ -9970,6 +9988,7 @@ get_delta_difference (tree from, tree to, > bool allow_inverse_p, > bool c_cast_p, tsubst_flags_t complain) > { > + auto_diagnostic_group d; > tree result; > > if (same_type_ignoring_top_level_qualifiers_p (from, to)) > @@ -10384,6 +10403,8 @@ convert_for_assignment (tree type, tree rhs, > { > if (complain & tf_error) > { > + auto_diagnostic_group d; > + > /* If the right-hand side has unknown type, then it is an > overloaded function. Call instantiate_type to get error > messages. */ > @@ -10406,7 +10427,6 @@ convert_for_assignment (tree type, tree rhs, > (rhs_loc, > has_loc ? &label : NULL, > has_loc ? highlight_colors::percent_h : NULL); > - auto_diagnostic_group d; > > switch (errtype) > { > @@ -11150,6 +11170,7 @@ check_return_expr (tree retval, bool *no_warning, bool *dangling) > if (!retval && !is_auto (pattern)) > { > /* Give a helpful error message. */ > + auto_diagnostic_group d; > error ("return-statement with no value, in function returning %qT", > pattern); > inform (input_location, "only plain %<auto%> return type can be " > diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc > index a0c8f833ac1..79b397a69fa 100644 > --- a/gcc/cp/typeck2.cc > +++ b/gcc/cp/typeck2.cc > @@ -302,6 +302,7 @@ cxx_incomplete_type_diagnostic (location_t loc, const_tree value, > if (TREE_CODE (type) == ERROR_MARK) > return false; > > + auto_diagnostic_group d; > if (value) > { > STRIP_ANY_LOCATION_WRAPPER (value);
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index 718601756dd..49af6d9367d 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -1431,6 +1431,7 @@ add_method (tree type, tree method, bool via_using) continue; } + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (method), "%q#D conflicts with version inherited from %qT", method, basef); @@ -1453,6 +1454,7 @@ add_method (tree type, tree method, bool via_using) } else { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (method), "%q#D cannot be overloaded with %q#D", method, fn); inform (DECL_SOURCE_LOCATION (fn), @@ -1604,6 +1606,7 @@ handle_using_decl (tree using_decl, tree t) ; else if (is_overloaded_fn (old_value)) { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T " "because of local method %q#D with same name", using_decl, t, old_value); @@ -1613,6 +1616,7 @@ handle_using_decl (tree using_decl, tree t) } else if (!DECL_ARTIFICIAL (old_value)) { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T " "because of local member %q#D with same name", using_decl, t, old_value); @@ -2550,6 +2554,7 @@ maybe_warn_about_overly_private_class (tree t) if (!nonprivate_ctor) { + auto_diagnostic_group d; bool w = warning (OPT_Wctor_dtor_privacy, "%q#T only defines private constructors and has " "no friends", t); @@ -3818,6 +3823,7 @@ check_field_decl (tree field, if (TREE_CODE (t) == UNION_TYPE && cxx_dialect < cxx11) { static bool warned; + auto_diagnostic_group d; int oldcount = errorcount; if (TYPE_NEEDS_CONSTRUCTING (type)) error ("member %q+#D with constructor not allowed in union", @@ -4134,6 +4140,7 @@ check_field_decls (tree t, tree *access_decls, if (default_init_member && TREE_CODE (t) == UNION_TYPE) { + auto_diagnostic_group d; error ("multiple fields in union %qT initialized", t); inform (DECL_SOURCE_LOCATION (default_init_member), "initialized member %q+D declared here", @@ -4212,6 +4219,7 @@ check_field_decls (tree t, tree *access_decls, && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) && !(TYPE_HAS_COPY_CTOR (t) && TYPE_HAS_COPY_ASSIGN (t))) { + auto_diagnostic_group d; if (warning (OPT_Weffc__, "%q#T has pointer data members", t)) { if (! TYPE_HAS_COPY_CTOR (t)) @@ -8916,6 +8924,7 @@ resolve_address_of_overloaded_function (tree target_type, /* There were *no* matches. */ if (complain & tf_error) { + auto_diagnostic_group d; error ("no matches converting function %qD to type %q#T", OVL_NAME (overload), target_type); @@ -8943,6 +8952,7 @@ resolve_address_of_overloaded_function (tree target_type, { if (complain & tf_error) { + auto_diagnostic_group d; error ("converting overloaded function %qD to type %q#T is ambiguous", OVL_NAME (overload), target_type); @@ -9400,6 +9410,8 @@ note_name_declared_in_class (tree name, tree decl) else /* Make it an error. */ global_dc->m_pedantic_errors = 1; + + auto_diagnostic_group d; if (pedwarn (location_of (decl), OPT_Wchanges_meaning, "declaration of %q#D changes meaning of %qD", decl, OVL_NAME (decl))) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index f79407f2cdb..ebfcdefd284 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -1005,6 +1005,7 @@ associate_classtype_constraints (tree type) } if (!equivalent_constraints (ci, orig_ci)) { + auto_diagnostic_group d; error ("%qT does not match original declaration", type); tree tmpl = CLASSTYPE_TI_TEMPLATE (type); location_t loc = DECL_SOURCE_LOCATION (tmpl); @@ -3183,9 +3184,9 @@ diagnose_trait_expr (tree expr, tree args) break; case CPTK_IS_CONSTRUCTIBLE: if (!t2) - inform (loc, " %qT is not default constructible", t1); + inform (loc, " %qT is not default constructible", t1); else - inform (loc, " %qT is not constructible from %qE", t1, t2); + inform (loc, " %qT is not constructible from %qE", t1, t2); break; case CPTK_IS_CONVERTIBLE: inform (loc, " %qT is not convertible from %qE", t2, t1); @@ -3204,9 +3205,9 @@ diagnose_trait_expr (tree expr, tree args) break; case CPTK_IS_INVOCABLE: if (!t2) - inform (loc, " %qT is not invocable", t1); + inform (loc, " %qT is not invocable", t1); else - inform (loc, " %qT is not invocable by %qE", t1, t2); + inform (loc, " %qT is not invocable by %qE", t1, t2); break; case CPTK_IS_LAYOUT_COMPATIBLE: inform (loc, " %qT is not layout compatible with %qT", t1, t2); @@ -3233,14 +3234,14 @@ diagnose_trait_expr (tree expr, tree args) inform (loc, " %qT is not nothrow constructible from %qE", t1, t2); break; case CPTK_IS_NOTHROW_CONVERTIBLE: - inform (loc, " %qT is not nothrow convertible from %qE", t2, t1); + inform (loc, " %qT is not nothrow convertible from %qE", t2, t1); break; case CPTK_IS_NOTHROW_INVOCABLE: - if (!t2) - inform (loc, " %qT is not nothrow invocable", t1); - else - inform (loc, " %qT is not nothrow invocable by %qE", t1, t2); - break; + if (!t2) + inform (loc, " %qT is not nothrow invocable", t1); + else + inform (loc, " %qT is not nothrow invocable by %qE", t1, t2); + break; case CPTK_IS_OBJECT: inform (loc, " %qT is not an object type", t1); break; diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 145ec4b1d16..cde013b09ad 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -300,6 +300,7 @@ find_coro_traits_template_decl (location_t kw) { if (!traits_error_emitted) { + auto_diagnostic_group d; gcc_rich_location richloc (kw); error_at (&richloc, "coroutines require a traits template; cannot" " find %<%E::%E%>", std_node, coro_traits_identifier); @@ -627,6 +628,7 @@ coro_promise_type_found_p (tree fndecl, location_t loc) tf_none); if (has_ret_void && has_ret_val) { + auto_diagnostic_group d; location_t ploc = DECL_SOURCE_LOCATION (fndecl); if (!coro_info->coro_co_return_error_emitted) error_at (ploc, "the coroutine promise type %qT declares both" @@ -1017,6 +1019,7 @@ coro_diagnose_throwing_fn (tree fndecl) { if (!TYPE_NOTHROW_P (TREE_TYPE (fndecl))) { + auto_diagnostic_group d; location_t f_loc = cp_expr_loc_or_loc (fndecl, DECL_SOURCE_LOCATION (fndecl)); error_at (f_loc, "the expression %qE is required to be non-throwing", diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc index 7b4bd8a9dc4..df02b8faaf5 100644 --- a/gcc/cp/cvt.cc +++ b/gcc/cp/cvt.cc @@ -1933,6 +1933,7 @@ build_expr_type_conversion (int desires, tree expr, bool complain) { if (complain) { + auto_diagnostic_group d; error ("ambiguous default type conversion from %qT", basetype); inform (input_location, diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 86d2bfab22d..4621264f126 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -1456,6 +1456,7 @@ validate_constexpr_redeclaration (tree old_decl, tree new_decl) if (DECL_IMMEDIATE_FUNCTION_P (old_decl) || DECL_IMMEDIATE_FUNCTION_P (new_decl)) kind = "consteval"; + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (new_decl), "redeclaration %qD differs in %qs " "from previous declaration", new_decl, @@ -1566,6 +1567,7 @@ duplicate_function_template_decls (tree newdecl, tree olddecl) if (template_heads_equivalent_p (newdecl, olddecl) && function_requirements_equivalent_p (newres, oldres)) { + auto_diagnostic_group d; error ("ambiguating new declaration %q+#D", newdecl); inform (DECL_SOURCE_LOCATION (olddecl), "old declaration %q#D", olddecl); @@ -1901,6 +1903,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) return NULL_TREE; /* There can only be one! */ + auto_diagnostic_group d; if (TREE_CODE (newdecl) == TEMPLATE_DECL && check_raw_literal_operator (olddecl)) error_at (newdecl_loc, @@ -1923,6 +1926,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) /* One is an implicit typedef, that's ok. */ return NULL_TREE; + auto_diagnostic_group d; error ("%q#D redeclared as different kind of entity", newdecl); inform (olddecl_loc, "previous declaration %q#D", olddecl); @@ -1946,6 +1950,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) if (TREE_CODE (oldres) == TYPE_DECL || TREE_CODE (newres) == TYPE_DECL) { + auto_diagnostic_group d; error_at (newdecl_loc, "conflicting declaration of template %q#D", newdecl); inform (olddecl_loc, @@ -1966,6 +1971,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) { if (DECL_EXTERN_C_P (newdecl) && DECL_EXTERN_C_P (olddecl)) { + auto_diagnostic_group d; error_at (newdecl_loc, "conflicting declaration of C function %q#D", newdecl); @@ -1987,6 +1993,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) // And the same constraints. && equivalently_constrained (newdecl, olddecl)) { + auto_diagnostic_group d; error_at (newdecl_loc, "ambiguating new declaration of %q#D", newdecl); inform (olddecl_loc, @@ -1998,6 +2005,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) } else { + auto_diagnostic_group d; error_at (newdecl_loc, "conflicting declaration %q#D", newdecl); inform (olddecl_loc, "previous declaration as %q#D", olddecl); @@ -2009,6 +2017,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) { /* OMP UDRs are never duplicates. */ gcc_assert (DECL_OMP_DECLARE_REDUCTION_P (olddecl)); + auto_diagnostic_group d; error_at (newdecl_loc, "redeclaration of %<pragma omp declare reduction%>"); inform (olddecl_loc, @@ -2310,10 +2319,13 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) { if (merge_attr) { - if (diagnose_mismatched_attributes (olddecl, newdecl)) - inform (olddecl_loc, DECL_INITIAL (olddecl) - ? G_("previous definition of %qD here") - : G_("previous declaration of %qD here"), olddecl); + { + auto_diagnostic_group d; + if (diagnose_mismatched_attributes (olddecl, newdecl)) + inform (olddecl_loc, DECL_INITIAL (olddecl) + ? G_("previous definition of %qD here") + : G_("previous declaration of %qD here"), olddecl); + } /* [dcl.attr.noreturn]: The first declaration of a function shall specify the noreturn attribute if any declaration of that function @@ -2326,6 +2338,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden) && cxx11_attribute_p (a) && get_attribute_namespace (a) == NULL_TREE) { + auto_diagnostic_group d; error_at (newdecl_loc, "function %qD declared %<[[noreturn]]%> " "but its first declaration was not", newdecl); inform (olddecl_loc, "previous declaration of %qD", olddecl); @@ -3596,6 +3609,7 @@ lookup_label_1 (tree id, bool making_local_p) if (old->binding_level == current_binding_level) { + auto_diagnostic_group d; error ("local label %qE conflicts with existing label", id); inform (DECL_SOURCE_LOCATION (old->label_decl), "previous label"); return NULL; @@ -3711,6 +3725,7 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, bool exited_omp, const location_t *locus, vec<tree,va_gc> *computed) { + auto_diagnostic_group d; cp_binding_level *b; bool complained = false; int identified = 0; @@ -3857,6 +3872,7 @@ check_switch_goto (cp_binding_level* level) void check_goto_1 (named_label_entry *ent, bool computed) { + auto_diagnostic_group d; tree decl = ent->label_decl; /* If the label hasn't been defined yet, defer checking. */ @@ -4530,6 +4546,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, { if (complain & tf_error) { + auto_diagnostic_group d; error ("lookup of %qT in %qT is ambiguous", name, context); print_candidates (t); } @@ -4625,6 +4642,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list, { if (complain & tf_error) { + auto_diagnostic_group d; error ("template parameters do not match template %qD", tmpl); inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here", tmpl); @@ -5763,6 +5781,7 @@ check_tag_decl (cp_decl_specifier_seq *declspecs, No attribute-specifier-seq shall appertain to an explicit instantiation. */ { + auto_diagnostic_group d; if (warning_at (loc, OPT_Wattributes, "attribute ignored in explicit instantiation %q#T", declared_type)) @@ -5998,6 +6017,7 @@ start_decl (const cp_declarator *declarator, /* OK, specialization was already checked. */; else if (variable_template_p (field) && !this_tmpl) { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (decl), "non-member-template declaration of %qD", decl); inform (DECL_SOURCE_LOCATION (field), "does not match " @@ -6660,6 +6680,7 @@ maybe_commonize_var (tree decl) msg = G_("sorry: semantics of inline function " "static data %q#D are wrong (you%'ll wind " "up with multiple copies)"); + auto_diagnostic_group d; if (warning_at (DECL_SOURCE_LOCATION (decl), 0, msg, decl)) inform (DECL_SOURCE_LOCATION (decl), @@ -6697,6 +6718,7 @@ check_for_uninitialized_const_var (tree decl, bool constexpr_context_p, if (!field) return true; + auto_diagnostic_group d; bool show_notes = true; if (!constexpr_context_p || cxx_dialect >= cxx20) @@ -7061,6 +7083,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p, { if (field && TREE_CODE (field) == TREE_LIST) { + auto_diagnostic_group g; error ("request for member %qD is ambiguous", d->cur->index); print_candidates (field); @@ -7883,6 +7906,7 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups) { static int explained = 0; + auto_diagnostic_group d; if (cxx_dialect < cxx11) error ("initializer invalid for static member with constructor"); else if (cxx_dialect < cxx17) @@ -8559,6 +8583,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, && !type_uses_auto (type) && !COMPLETE_TYPE_P (complete_type (type))) { + auto_diagnostic_group d; error_at (location_of (decl), "deduced type %qT for %qD is incomplete", type, decl); cxx_incomplete_type_inform (type); @@ -9058,6 +9083,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, complete_type (TREE_TYPE (decl)); if (!omp_mappable_type (TREE_TYPE (decl))) { + auto_diagnostic_group d; error ("%q+D in declare target directive does not have mappable" " type", decl); if (TREE_TYPE (decl) != error_mark_node @@ -9113,6 +9139,7 @@ find_decomp_class_base (location_t loc, tree type, tree ret) return type; else if (ANON_AGGR_TYPE_P (TREE_TYPE (field))) { + auto_diagnostic_group d; if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE) error_at (loc, "cannot decompose class type %qT because it has an " "anonymous struct member", type); @@ -9124,6 +9151,7 @@ find_decomp_class_base (location_t loc, tree type, tree ret) } else if (!accessible_p (type, field, true)) { + auto_diagnostic_group d; error_at (loc, "cannot decompose inaccessible member %qD of %qT", field, type); inform (DECL_SOURCE_LOCATION (field), @@ -9424,6 +9452,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp) if (count != eltscnt) { cnt_mismatch: + auto_diagnostic_group d; if (count > eltscnt) error_n (loc, count, "%u name provided for structured binding", @@ -9504,6 +9533,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp) } if (!tree_fits_uhwi_p (tsize)) { + auto_diagnostic_group d; error_n (loc, count, "%u name provided for structured binding", "%u names provided for structured binding", count); @@ -10095,6 +10125,7 @@ expand_static_init (tree decl, tree init) if (CP_DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl) && !DECL_FUNCTION_SCOPE_P (decl)) { + auto_diagnostic_group d; location_t dloc = DECL_SOURCE_LOCATION (decl); if (init) error_at (dloc, "non-local variable %qD declared %<__thread%> " @@ -10869,6 +10900,7 @@ grokfndecl (tree ctype, if (in_namespace == NULL_TREE && CP_DECL_CONTEXT (decl) != CP_TYPE_CONTEXT (type)) { + auto_diagnostic_group d; error_at (location, "deduction guide %qD must be declared in the " "same scope as %qT", decl, type); inform (location_of (type), " declared here"); @@ -10877,6 +10909,7 @@ grokfndecl (tree ctype, if (DECL_CLASS_SCOPE_P (decl) && current_access_specifier != declared_access (TYPE_NAME (type))) { + auto_diagnostic_group d; error_at (location, "deduction guide %qD must have the same access " "as %qT", decl, type); inform (location_of (type), " declared here"); @@ -10896,6 +10929,7 @@ grokfndecl (tree ctype, /* [over.literal]/6: Literal operators shall not have C linkage. */ if (DECL_LANGUAGE (decl) == lang_c) { + auto_diagnostic_group d; error_at (location, "literal operator with C linkage"); maybe_show_extern_c_location (); return NULL_TREE; @@ -11062,6 +11096,7 @@ grokfndecl (tree ctype, } else if (DECL_DEFAULTED_FN (old_decl)) { + auto_diagnostic_group d; error ("definition of explicitly-defaulted %q+D", decl); inform (DECL_SOURCE_LOCATION (old_decl), "%q#D explicitly defaulted here", old_decl); @@ -13216,6 +13251,7 @@ grokdeclarator (const cp_declarator *declarator, && !diagnose_misapplied_contracts (declspecs->std_attributes)) { location_t attr_loc = declspecs->locations[ds_std_attribute]; + auto_diagnostic_group d; if (any_nonignored_attribute_p (declspecs->std_attributes) && warning_at (attr_loc, OPT_Wattributes, "attribute ignored")) inform (attr_loc, "an attribute that appertains to a type-specifier " @@ -13287,6 +13323,7 @@ grokdeclarator (const cp_declarator *declarator, && (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ENUMERAL_TYPE))) { + auto_diagnostic_group d; if (warning_at (declarator->parenthesized, OPT_Wparentheses, "unnecessary parentheses in declaration of %qs", name)) @@ -13448,6 +13485,7 @@ grokdeclarator (const cp_declarator *declarator, /* OK for C++11 lambdas. */; else if (cxx_dialect < cxx14) { + auto_diagnostic_group d; error_at (typespec_loc, "%qs function uses " "%<auto%> type specifier without " "trailing return type", name); @@ -13499,6 +13537,7 @@ grokdeclarator (const cp_declarator *declarator, } else if (!late_return_type) { + auto_diagnostic_group d; error_at (declarator->id_loc, "deduction guide " "for %qT must have trailing return " "type", TREE_TYPE (tmpl)); @@ -14735,6 +14774,7 @@ grokdeclarator (const cp_declarator *declarator, tree tmpl = TREE_OPERAND (unqualified_id, 0); if (variable_template_p (tmpl)) { + auto_diagnostic_group d; error_at (id_loc, "specialization of variable template " "%qD declared as function", tmpl); inform (DECL_SOURCE_LOCATION (tmpl), @@ -14801,6 +14841,7 @@ grokdeclarator (const cp_declarator *declarator, { if (unqualified_id) { + auto_diagnostic_group d; error_at (id_loc, "field %qD has incomplete type %qT", unqualified_id, type); cxx_incomplete_type_inform (strip_array_types (type)); @@ -14846,6 +14887,7 @@ grokdeclarator (const cp_declarator *declarator, && !all_attributes_are_contracts_p (*attrlist)) { *attrlist = NULL_TREE; + auto_diagnostic_group d; if (warning_at (id_loc, OPT_Wattributes, "attribute ignored")) inform (id_loc, "an attribute that appertains to a friend " "declaration that is not a definition is ignored"); @@ -16357,6 +16399,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, && !DECL_SELF_REFERENCE_P (decl) && tag_code != typename_type) { + auto_diagnostic_group d; if (alias_template_specialization_p (type, nt_opaque)) error ("using alias template specialization %qT after %qs", type, tag_name (tag_code)); @@ -16371,6 +16414,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, && tag_code != enum_type && tag_code != typename_type) { + auto_diagnostic_group d; error ("%qT referred to as %qs", type, tag_name (tag_code)); inform (location_of (type), "%qT has a previous declaration here", type); return error_mark_node; @@ -16378,6 +16422,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, else if (TREE_CODE (type) != ENUMERAL_TYPE && tag_code == enum_type) { + auto_diagnostic_group d; error ("%qT referred to as enum", type); inform (location_of (type), "%qT has a previous declaration here", type); return error_mark_node; @@ -16435,6 +16480,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, if (TREE_CODE (decl) == TREE_LIST) { + auto_diagnostic_group d; error ("reference to %qD is ambiguous", name); print_candidates (decl); return error_mark_node; @@ -16444,6 +16490,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, && !template_header_p && how == TAG_how::CURRENT_ONLY) { + auto_diagnostic_group d; error ("class template %qD redeclared as non-template", name); inform (location_of (decl), "previous declaration here"); CLASSTYPE_ERRONEOUS (TREE_TYPE (decl)) = true; @@ -16494,6 +16541,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, && (!CLASSTYPE_TEMPLATE_INFO (t) || (!PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))))) { + auto_diagnostic_group d; error ("%qT is not a template", t); inform (location_of (t), "previous declaration here"); if (TYPE_CLASS_SCOPE_P (t) @@ -16630,6 +16678,7 @@ xref_tag (enum tag_types tag_code, tree name, && CLASS_TYPE_P (t) && CLASSTYPE_IS_TEMPLATE (t)) { + auto_diagnostic_group d; error ("redeclaration of %qT as a non-template", t); inform (location_of (t), "previous declaration %qD", t); return error_mark_node; @@ -17613,6 +17662,7 @@ cxx_simulate_enum_decl (location_t loc, const char *name, NULL_TREE, false, NULL); if (!OPAQUE_ENUM_P (enumtype)) { + auto_diagnostic_group d; error_at (loc, "multiple definition of %q#T", enumtype); inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)), "previous definition here"); @@ -18698,6 +18748,7 @@ finish_function (bool inline_p) else if (!current_function_returns_value && !current_function_returns_null) { + auto_diagnostic_group d; error ("no return statements in function returning %qT", DECL_SAVED_AUTO_RETURN_TYPE (fndecl)); inform (input_location, "only plain %<auto%> return type can be " diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 695d5f8d790..87cf0c567de 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -908,6 +908,7 @@ check_classfn (tree ctype, tree function, tree template_parms) if (DECL_CONV_FN_P (function)) fns = get_class_binding (ctype, conv_op_identifier); + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (function), "no declaration matches %q#D", function); if (fns) @@ -5002,6 +5003,7 @@ record_mangling (tree decl, bool need_warning) *slot = decl; else if (need_warning) { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (decl), "mangling of %q#D as %qE conflicts with a previous mangle", decl, id); @@ -5924,6 +5926,7 @@ mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */) sorry ("converting lambda that uses %<...%> to function pointer"); else if (complain & tf_error) { + auto_diagnostic_group d; if (DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST) { diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index 6c22ff55b46..03c19e4a7e4 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -4782,12 +4782,14 @@ qualified_name_lookup_error (tree scope, tree name, scope); else if (TREE_CODE (decl) == TREE_LIST) { + auto_diagnostic_group d; error_at (location, "reference to %<%T::%D%> is ambiguous", scope, name); print_candidates (decl); } else { + auto_diagnostic_group d; name_hint hint; if (SCOPED_ENUM_P (scope) && TREE_CODE (name) == IDENTIFIER_NODE) hint = suggest_alternative_in_scoped_enum (name, scope); diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc index 0231bd2507d..7b4abd1f56e 100644 --- a/gcc/cp/except.cc +++ b/gcc/cp/except.cc @@ -736,6 +736,7 @@ build_throw (location_t loc, tree exp, tsubst_flags_t complain) exp = moved; /* Call the copy constructor. */ + auto_diagnostic_group d; releasing_vec exp_vec (make_tree_vector_single (exp)); exp = build_special_member_call (object, complete_ctor_identifier, &exp_vec, TREE_TYPE (object), flags, diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index 20373d26988..be7fdb40dd6 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -662,6 +662,7 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain) { if (complain & tf_error) { + auto_diagnostic_group d; error ("default member initializer for %qD required before the end " "of its enclosing class", member); inform (location_of (init), "defined here"); @@ -2736,6 +2737,7 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, ++ error_count; if (complain) { + auto_diagnostic_group d; if (DECL_CONTEXT (field) == origin) { if (using_new) @@ -2764,6 +2766,7 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin, ++ error_count; if (complain) { + auto_diagnostic_group d; if (DECL_CONTEXT (field) == origin) { if (using_new) @@ -2890,6 +2893,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper) bool warned = false; if (nelts) nelts = fold_for_warn (nelts); + + auto_diagnostic_group d; if (nelts) if (CONSTANT_CLASS_P (nelts)) warned = warning_at (loc, OPT_Wplacement_new_, @@ -3408,6 +3413,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, { if (complain & tf_error) { + auto_diagnostic_group d; error ("request for member %qD is ambiguous", fnname); print_candidates (fns); } @@ -4125,6 +4131,7 @@ build_vec_delete_1 (location_t loc, tree base, tree maxindex, tree type, { if (complain & tf_error) { + auto_diagnostic_group d; int saved_errorcount = errorcount; if (permerror_opt (loc, OPT_Wdelete_incomplete, "operator %<delete []%> used on " @@ -5209,6 +5216,7 @@ build_delete (location_t loc, tree otype, tree addr, { if (complain & tf_error) { + auto_diagnostic_group d; int saved_errorcount = errorcount; if (permerror_opt (loc, OPT_Wdelete_incomplete, "operator %<delete%> used on " diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index 0770417810e..e17c00217b2 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -562,6 +562,7 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, else if (!dependent_type_p (type) && variably_modified_type_p (type, NULL_TREE)) { + auto_diagnostic_group d; sorry ("capture of variably-modified type %qT that is not an N3639 array " "of runtime bound", type); if (TREE_CODE (type) == ARRAY_TYPE @@ -600,6 +601,7 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, type = complete_type (type); if (!COMPLETE_TYPE_P (type)) { + auto_diagnostic_group d; error ("capture by copy of incomplete type %qT", type); cxx_incomplete_type_inform (type); return error_mark_node; @@ -757,6 +759,7 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) && this_capture_p && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_COPY) { + auto_diagnostic_group d; if (warning_at (LAMBDA_EXPR_LOCATION (lambda), OPT_Wdeprecated, "implicit capture of %qE via %<[=]%> is deprecated " "in C++20", this_identifier)) diff --git a/gcc/cp/lex.cc b/gcc/cp/lex.cc index 1110db7f8d0..79d9490c4ad 100644 --- a/gcc/cp/lex.cc +++ b/gcc/cp/lex.cc @@ -807,6 +807,7 @@ unqualified_fn_lookup_error (cp_expr name_expr) Note that we have the exact wording of the following message in the manual (trouble.texi, node "Name lookup"), so they need to be kept in synch. */ + auto_diagnostic_group d; permerror (loc, "there are no arguments to %qD that depend on a template " "parameter, so a declaration of %qD must be available", name, name); diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index 0b21656ed61..68a776d2c5a 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -1787,6 +1787,7 @@ synthesize_method (tree fndecl) int error_count = errorcount; int warning_count = warningcount + werrorcount; special_function_kind sfk = special_function_p (fndecl); + auto_diagnostic_group d; /* Reset the source location, we might have been previously deferred, and thus have saved where we were first needed. */ @@ -3558,6 +3559,7 @@ defaulted_late_check (tree fn) TREE_TYPE (TREE_TYPE (implicit_fn))) || !compare_fn_params (fn, implicit_fn)) { + auto_diagnostic_group d; error ("defaulted declaration %q+D does not match the " "expected signature", fn); inform (DECL_SOURCE_LOCATION (fn), @@ -3593,6 +3595,7 @@ defaulted_late_check (tree fn) { if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) { + auto_diagnostic_group d; error ("explicitly defaulted function %q+D cannot be declared " "%qs because the implicit declaration is not %qs:", fn, DECL_IMMEDIATE_FUNCTION_P (fn) ? "consteval" : "constexpr", diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 0f3e1d97c53..2eaf2bb6a74 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -11617,6 +11617,7 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef) { // FIXME:QOI Might be template specialization from a module, // not necessarily global module + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (decl), "conflicting global module declaration %#qD", decl); inform (DECL_SOURCE_LOCATION (existing), @@ -12672,6 +12673,7 @@ trees_in::read_enum_def (tree defn, tree maybe_template) if (known || values) { + auto_diagnostic_group d; error_at (DECL_SOURCE_LOCATION (maybe_dup), "definition of %qD does not match", maybe_dup); inform (DECL_SOURCE_LOCATION (defn), @@ -14487,6 +14489,7 @@ module_state::check_not_purview (location_t from) if (imp == this) { /* Cannot import the current module. */ + auto_diagnostic_group d; error_at (from, "cannot import module in its own purview"); inform (loc, "module %qs declared here", get_flatname ()); return false; @@ -17845,6 +17848,7 @@ module_state::deferred_macro (cpp_reader *reader, location_t loc, { /* If LOC is the first loc, this is the end of file check, which is a warning. */ + auto_diagnostic_group d; if (loc == MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (line_table, 0))) warning_at (loc, OPT_Winvalid_imported_macros, "inconsistent imported macro definition %qE", @@ -18119,6 +18123,7 @@ module_state::read_config (module_state_config &config) /* Reject when either is non-experimental or when experimental major versions differ. */ + auto_diagnostic_group d; bool reject_p = ((!IS_EXPERIMENTAL (my_ver) || !IS_EXPERIMENTAL (their_ver) || MODULE_MAJOR (my_ver) != MODULE_MAJOR (their_ver)) @@ -18932,6 +18937,7 @@ module_state::check_read (bool outermost, bool ok) if (int e = from ()->get_error ()) { + auto_diagnostic_group d; error_at (loc, "failed to read compiled module: %s", from ()->get_error (filename)); note_cmi_name (); @@ -19865,6 +19871,7 @@ declare_module (module_state *module, location_t from_loc, bool exporting_p, module_state *current = (*modules)[0]; if (module_purview_p () || module->loadedness > ML_CONFIG) { + auto_diagnostic_group d; error_at (from_loc, module_purview_p () ? G_("module already declared") : G_("module already imported")); @@ -20509,6 +20516,7 @@ init_modules (cpp_reader *reader) || (cpp_opts->deps.style != DEPS_NONE && !cpp_opts->deps.need_preprocessor_output)) { + auto_diagnostic_group d; warning (0, flag_dump_macros == 'M' ? G_("macro debug output may be incomplete with modules") : G_("module dependencies require preprocessing")); diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 8823ab71c60..ee3116910bc 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -2884,6 +2884,7 @@ supplement_binding (cxx_binding *binding, tree decl) void diagnose_name_conflict (tree decl, tree bval) { + auto_diagnostic_group d; if (TREE_CODE (decl) == TREE_CODE (bval) && TREE_CODE (decl) != NAMESPACE_DECL && !DECL_DECLARES_FUNCTION_P (decl) @@ -6190,6 +6191,7 @@ lookup_using_decl (tree scope, name_lookup &lookup) /* We can (independently) have ambiguous implicit typedefs. */ || (lookup.type && TREE_CODE (lookup.type) == TREE_LIST)) { + auto_diagnostic_group d; error ("reference to %qD is ambiguous", lookup.name); print_candidates (TREE_CODE (lookup.value) == TREE_LIST ? lookup.value : lookup.type); @@ -6321,6 +6323,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp) if (TREE_CODE (old) == TREE_LIST) { ambiguous: + auto_diagnostic_group d; DECL_CONTEXT (decl) = FROB_CONTEXT (scope); error ("reference to %qD is ambiguous", decl); print_candidates (old); @@ -6420,6 +6423,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp) { if (hidden_p) { + auto_diagnostic_group d; pedwarn (DECL_SOURCE_LOCATION (decl), 0, "%qD has not been declared within %qD", decl, scope); inform (DECL_SOURCE_LOCATION (found), @@ -8904,6 +8908,7 @@ finish_using_directive (tree target, tree attribs) if (current_binding_level->kind == sk_namespace && is_attribute_p ("strong", name)) { + auto_diagnostic_group d; if (warning (0, "%<strong%> using directive no longer supported") && CP_DECL_CONTEXT (target) == current_namespace) inform (DECL_SOURCE_LOCATION (target), @@ -9223,6 +9228,7 @@ push_namespace (tree name, bool make_inline) if (make_inline && !DECL_NAMESPACE_INLINE_P (ns)) { + auto_diagnostic_group d; error_at (input_location, "inline namespace must be specified at initial definition"); inform (DECL_SOURCE_LOCATION (ns), "%qD defined here", ns); @@ -9273,6 +9279,7 @@ add_imported_namespace (tree ctx, tree name, location_t loc, unsigned import, } else if (DECL_NAMESPACE_INLINE_P (decl) != inline_p) { + auto_diagnostic_group d; error_at (loc, "%s namespace %qD conflicts with reachable definition", inline_p ? "inline" : "non-inline", decl); inform (DECL_SOURCE_LOCATION (decl), "reachable %s definition here", diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 82f3903838e..8a5c4a8cd20 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -3500,6 +3500,7 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator, if (declarator && declarator->kind == cdk_function) { + auto_diagnostic_group d; error_at (type_location, "new types may not be defined in a return type"); inform (type_location, @@ -5082,24 +5083,27 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) } } - bool complained - = emit_diagnostic (kind, input_location, opt, - "unable to find numeric literal operator %qD", name); - - if (!complained) - /* Don't inform either. */; - else if (i14) - { - inform (token->location, "add %<using namespace std::complex_literals%> " - "(from %<<complex>%>) to enable the C++14 user-defined literal " - "suffixes"); - if (ext) - inform (token->location, "or use %<j%> instead of %<i%> for the " - "GNU built-in suffix"); - } - else if (!ext) - inform (token->location, "use %<-fext-numeric-literals%> " - "to enable more built-in suffixes"); + { + auto_diagnostic_group d; + bool complained + = emit_diagnostic (kind, input_location, opt, + "unable to find numeric literal operator %qD", name); + + if (!complained) + /* Don't inform either. */; + else if (i14) + { + inform (token->location, "add %<using namespace std::complex_literals%> " + "(from %<<complex>%>) to enable the C++14 user-defined literal " + "suffixes"); + if (ext) + inform (token->location, "or use %<j%> instead of %<i%> for the " + "GNU built-in suffix"); + } + else if (!ext) + inform (token->location, "use %<-fext-numeric-literals%> " + "to enable more built-in suffixes"); + } if (kind == DK_ERROR) value = error_mark_node; @@ -7155,6 +7159,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, if (TREE_CODE (tid) == TEMPLATE_ID_EXPR && TREE_CODE (TREE_OPERAND (tid, 0)) != IDENTIFIER_NODE) { + auto_diagnostic_group d; tree tmpl = NULL_TREE; if (is_overloaded_fn (tid)) { @@ -9632,10 +9637,13 @@ cp_parser_new_expression (cp_parser* parser) message for this case. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)) { - error_at (token->location, - "array bound forbidden after parenthesized type-id"); - inform (token->location, - "try removing the parentheses around the type-id"); + { + auto_diagnostic_group d; + error_at (token->location, + "array bound forbidden after parenthesized type-id"); + inform (token->location, + "try removing the parentheses around the type-id"); + } cp_parser_direct_new_declarator (parser); } } @@ -10431,6 +10439,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, && token->type == CPP_RSHIFT && !parser->greater_than_is_operator_p) { + auto_diagnostic_group d; if (warning_at (token->location, OPT_Wc__11_compat, "%<>>%> operator is treated" " as two right angle brackets in C++11")) @@ -11705,6 +11714,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) else if (!VAR_P (capture_init_expr) && TREE_CODE (capture_init_expr) != PARM_DECL) { + auto_diagnostic_group d; error_at (capture_token->location, "capture of non-variable %qE", capture_init_expr); @@ -11716,6 +11726,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) if (VAR_P (capture_init_expr) && decl_storage_duration (capture_init_expr) != dk_auto) { + auto_diagnostic_group d; if (pedwarn (capture_token->location, 0, "capture of variable " "%qD with non-automatic storage duration", capture_init_expr)) @@ -15215,6 +15226,7 @@ cp_parser_module_declaration (cp_parser *parser, module_parse mp_state, } else if (scope != global_namespace) { + auto_diagnostic_group d; error_at (token->location, "module-declaration must be at global scope"); inform (DECL_SOURCE_LOCATION (scope), "scope opened here"); goto skip_eol; @@ -15292,19 +15304,22 @@ cp_parser_import_declaration (cp_parser *parser, module_parse mp_state, if (mp_state == MP_PURVIEW || mp_state == MP_PRIVATE) { + auto_diagnostic_group d; error_at (token->location, "post-module-declaration" " imports must be contiguous"); - note_lexer: inform (token->location, "perhaps insert a line break after" " %<import%>, or other disambiguation, to prevent this" " being considered a module control-line"); - skip_eol: cp_parser_skip_to_pragma_eol (parser, token); } else if (current_scope () != global_namespace) { + auto_diagnostic_group d; error_at (token->location, "import-declaration must be at global scope"); - goto note_lexer; + inform (token->location, "perhaps insert a line break after" + " %<import%>, or other disambiguation, to prevent this" + " being considered a module control-line"); + cp_parser_skip_to_pragma_eol (parser, token); } else { @@ -15332,7 +15347,10 @@ cp_parser_import_declaration (cp_parser *parser, module_parse mp_state, tree attrs = cp_parser_attributes_opt (parser); if (!mod || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)) - goto skip_eol; + { + cp_parser_skip_to_pragma_eol (parser, token); + return; + } cp_parser_require_pragma_eol (parser, token); if (mp_state == MP_PURVIEW_IMPORTS || mp_state == MP_PRIVATE_IMPORTS) @@ -15625,6 +15643,7 @@ cp_parser_declaration (cp_parser* parser, tree prefix_attrs) if (!c_dialect_objc ()) { location_t where = get_finish (t2->location); + auto_diagnostic_group d; warning_at (token1->location, OPT_Wattributes, "attributes are" " not permitted in this position"); where = linemap_position_for_loc_and_offset (line_table, @@ -16876,6 +16895,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, if (decl_specs->std_attributes) { + auto_diagnostic_group d; error_at (decl_specs->locations[ds_std_attribute], "standard attributes in middle of decl-specifiers"); inform (decl_specs->locations[ds_std_attribute], @@ -19125,6 +19145,7 @@ cp_parser_template_id (cp_parser *parser, } /* Otherwise, emit an error about the invalid digraph, but continue parsing because we got our argument list. */ + auto_diagnostic_group d; if (permerror (next_token->location, "%<<::%> cannot begin a template-argument list")) { @@ -19164,6 +19185,7 @@ cp_parser_template_id (cp_parser *parser, /* C++20 says that "function-name < a;" is now ill-formed. */ if (cp_parser_error_occurred (parser)) { + auto_diagnostic_group d; error_at (token->location, "invalid template-argument-list"); inform (token->location, "function name as the left hand " "operand of %<<%> is ill-formed in C++20; wrap the " @@ -19409,10 +19431,13 @@ cp_parser_template_name (cp_parser* parser, cp_token_position start = 0; /* Explain what went wrong. */ - error_at (token->location, "non-template %qD used as template", - identifier); - inform (token->location, "use %<%T::template %D%> to indicate that it is a template", - parser->scope, identifier); + { + auto_diagnostic_group d; + error_at (token->location, "non-template %qD used as template", + identifier); + inform (token->location, "use %<%T::template %D%> to indicate " + "that it is a template", parser->scope, identifier); + } /* If parsing tentatively, find the location of the "<" token. */ if (cp_parser_simulate_error (parser)) start = cp_lexer_token_position (parser->lexer, true); @@ -20080,6 +20105,7 @@ cp_parser_explicit_specialization (cp_parser* parser) bool need_lang_pop = current_lang_name == lang_name_c; if (need_lang_pop) { + auto_diagnostic_group d; error_at (token->location, "template specialization with C linkage"); maybe_show_extern_c_location (); @@ -20912,6 +20938,7 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc, { if (!tentative) { + auto_diagnostic_group d; error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); inform (DECL_SOURCE_LOCATION (con), "concept defined here"); } @@ -21525,6 +21552,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, "attributes ignored on template instantiation"); else if (is_friend && cxx11_attribute_p (attributes)) { + auto_diagnostic_group d; if (warning (OPT_Wattributes, "attribute ignored")) inform (input_location, "an attribute that appertains to a friend " "declaration that is not a definition is ignored"); @@ -21877,6 +21905,7 @@ cp_parser_enum_specifier (cp_parser* parser) } else { + auto_diagnostic_group d; error_at (type_start_token->location, "multiple definition of %q#T", type); inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)), @@ -22924,6 +22953,7 @@ cp_parser_asm_definition (cp_parser* parser) case RID_VOLATILE: if (volatile_loc) { + auto_diagnostic_group d; error_at (loc, "duplicate %<asm%> qualifier %qT", token->u.value); inform (volatile_loc, "first seen here"); @@ -22941,6 +22971,7 @@ cp_parser_asm_definition (cp_parser* parser) case RID_INLINE: if (inline_loc) { + auto_diagnostic_group d; error_at (loc, "duplicate %<asm%> qualifier %qT", token->u.value); inform (inline_loc, "first seen here"); @@ -22955,6 +22986,7 @@ cp_parser_asm_definition (cp_parser* parser) case RID_GOTO: if (goto_loc) { + auto_diagnostic_group d; error_at (loc, "duplicate %<asm%> qualifier %qT", token->u.value); inform (goto_loc, "first seen here"); @@ -23768,12 +23800,13 @@ cp_parser_init_declarator (cp_parser* parser, attributes -- but ignores them. Made a permerror in GCC 8. */ if (cp_parser_allow_gnu_extensions_p (parser) && initialization_kind == CPP_OPEN_PAREN - && cp_parser_attributes_opt (parser) - && permerror (input_location, - "attributes after parenthesized initializer ignored")) + && cp_parser_attributes_opt (parser)) { static bool hint; - if (flag_permissive && !hint) + auto_diagnostic_group d; + if (permerror (input_location, + "attributes after parenthesized initializer ignored") + && flag_permissive && !hint) { hint = true; inform (input_location, @@ -24474,6 +24507,7 @@ cp_parser_direct_declarator (cp_parser* parser, else if (qualifying_scope && CLASSTYPE_USE_TEMPLATE (name_type)) { + auto_diagnostic_group d; error_at (declarator_id_start_token->location, "invalid use of constructor as a template"); inform (declarator_id_start_token->location, @@ -27860,6 +27894,7 @@ cp_parser_class_head (cp_parser* parser, if (type != error_mark_node && (COMPLETE_TYPE_P (type) || TYPE_BEING_DEFINED (type))) { + auto_diagnostic_group d; error_at (type_start_token->location, "redefinition of %q#T", type); inform (location_of (type), "previous definition of %q#T", @@ -28310,6 +28345,7 @@ cp_parser_member_declaration (cp_parser* parser) && cxx11_attribute_p (decl_specifiers.attributes)) { decl_specifiers.attributes = NULL_TREE; + auto_diagnostic_group d; if (warning_at (decl_spec_token_start->location, OPT_Wattributes, "attribute ignored")) inform (decl_spec_token_start->location, "an attribute " @@ -32408,6 +32444,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, cp_parser_error, so we incorporate its actions directly. */ if (!cp_parser_simulate_error (parser)) { + auto_diagnostic_group d; error_at (name_location, "reference to %qD is ambiguous", name); print_candidates (decl); @@ -33219,6 +33256,7 @@ cp_parser_explicit_template_declaration (cp_parser* parser, bool member_p) A template ... shall not have C linkage. */ if (current_lang_name == lang_name_c) { + auto_diagnostic_group d; error_at (location, "template with C linkage"); maybe_show_extern_c_location (); /* Give it C++ linkage to avoid confusing other parts of the @@ -35195,6 +35233,7 @@ cp_parser_check_class_key (cp_parser *parser, location_t key_loc, bool seen_as_union = TREE_CODE (type) == UNION_TYPE; if (seen_as_union != (class_key == union_type)) { + auto_diagnostic_group d; if (permerror (input_location, "%qs tag used in naming %q#T", class_key == union_type ? "union" : class_key == record_type ? "struct" : "class", diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 2db59213c54..633b7b4f578 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -1124,6 +1124,7 @@ maybe_process_partial_specialization (tree type) if (current_namespace != decl_namespace_context (tmpl)) { + auto_diagnostic_group d; if (permerror (input_location, "specialization of %qD in different namespace", type)) @@ -2466,6 +2467,7 @@ determine_specialization (tree template_id, if (templates == NULL_TREE && candidates == NULL_TREE) { + auto_diagnostic_group d; error ("template-id %qD for %q+D does not match any template " "declaration", template_id, decl); if (header_mismatch) @@ -2480,6 +2482,7 @@ determine_specialization (tree template_id, || (candidates && TREE_CHAIN (candidates)) || (templates && candidates)) { + auto_diagnostic_group d; error ("ambiguous template specialization %qD for %q+D", template_id, decl); candidates = chainon (candidates, templates); @@ -4306,6 +4309,7 @@ check_for_bare_parameter_packs (tree t, location_t loc /* = UNKNOWN_LOCATION */) if (parameter_packs) { + auto_diagnostic_group d; error_at (loc, "parameter packs not expanded with %<...%>:"); while (parameter_packs) { @@ -4450,6 +4454,7 @@ check_template_shadow (tree decl) if (DECL_SELF_REFERENCE_P (decl)) return false; + auto_diagnostic_group d; if (DECL_TEMPLATE_PARM_P (decl)) error ("declaration of template parameter %q+D shadows " "template parameter", decl); @@ -5136,7 +5141,6 @@ process_partial_specialization (tree decl) int nargs = TREE_VEC_LENGTH (inner_args); int ntparms; int i; - bool did_error_intro = false; struct template_parm_data tpd; struct template_parm_data tpd2; @@ -5190,24 +5194,29 @@ process_partial_specialization (tree decl) NULL, /*include_nondeduced_p=*/false); } - for (i = 0; i < ntparms; ++i) - if (tpd.parms[i] == 0) - { - /* One of the template parms was not used in a deduced context in the - specialization. */ - if (!did_error_intro) - { - error ("template parameters not deducible in " - "partial specialization:"); - did_error_intro = true; - } - inform (input_location, " %qD", - TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); - } + { + auto_diagnostic_group d; + bool did_error_intro = false; + for (i = 0; i < ntparms; ++i) + if (tpd.parms[i] == 0) + { + /* One of the template parms was not used in a deduced context in the + specialization. */ + if (!did_error_intro) + { + error ("template parameters not deducible in " + "partial specialization:"); + did_error_intro = true; + } - if (did_error_intro) - return error_mark_node; + inform (input_location, " %qD", + TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); + } + + if (did_error_intro) + return error_mark_node; + } /* [temp.class.spec] @@ -5219,6 +5228,7 @@ process_partial_specialization (tree decl) && (!flag_concepts || !strictly_subsumes (current_template_constraints (), maintmpl))) { + auto_diagnostic_group d; if (!flag_concepts) error ("partial specialization %q+D does not specialize " "any template arguments; to define the primary template, " @@ -5236,6 +5246,7 @@ process_partial_specialization (tree decl) parameters. */ if (nargs < DECL_NTPARMS (maintmpl)) { + auto_diagnostic_group d; error ("partial specialization is not more specialized than the " "primary template because it replaces multiple parameters " "with a pack expansion"); @@ -5246,6 +5257,7 @@ process_partial_specialization (tree decl) else if (nargs > DECL_NTPARMS (maintmpl)) { + auto_diagnostic_group d; error ("too many arguments for partial specialization %qT", type); inform (DECL_SOURCE_LOCATION (maintmpl), "primary template here"); /* Avoid crash below. */ @@ -6136,6 +6148,7 @@ push_template_decl (tree decl, bool is_friend) (TI_ARGS (tinfo), TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl))))) { + auto_diagnostic_group d; error ("template arguments to %qD do not match original " "template %qD", decl, DECL_TEMPLATE_RESULT (tmpl)); if (!uses_template_parms (TI_ARGS (tinfo))) @@ -6341,6 +6354,7 @@ redeclare_class_template (tree type, tree parms, tree cons) if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms)) { + auto_diagnostic_group d; error_n (input_location, TREE_VEC_LENGTH (parms), "redeclared with %d template parameter", "redeclared with %d template parameters", @@ -6857,6 +6871,7 @@ convert_nontype_argument_function (tree type, tree expr, { if (complain & tf_error) { + auto_diagnostic_group d; location_t loc = cp_expr_loc_or_input_loc (expr); error_at (loc, "%qE is not a valid template argument for type %qT", expr, type); @@ -6927,6 +6942,7 @@ check_valid_ptrmem_cst_expr (tree type, tree expr, return true; if (complain & tf_error) { + auto_diagnostic_group d; location_t loc = cp_expr_loc_or_input_loc (orig_expr); error_at (loc, "%qE is not a valid template argument for type %qT", orig_expr, type); @@ -7790,6 +7806,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (complain & tf_error) { + auto_diagnostic_group d; error ("%qE is not a valid template argument for type %qT " "because it is a pointer", expr, type); inform (input_location, "try using %qE instead", @@ -8648,6 +8665,7 @@ convert_template_argument (tree parm, { if (complain & tf_error) { + auto_diagnostic_group d; error ("type/value mismatch at argument %d in template " "parameter list for %qD", i + 1, in_decl); @@ -8682,6 +8700,7 @@ convert_template_argument (tree parm, { if (in_decl && (complain & tf_error)) { + auto_diagnostic_group d; error ("type/value mismatch at argument %d in template " "parameter list for %qD", i + 1, in_decl); @@ -8732,6 +8751,7 @@ convert_template_argument (tree parm, { if (in_decl && (complain & tf_error)) { + auto_diagnostic_group d; error ("type/value mismatch at argument %d in " "template parameter list for %qD", i + 1, in_decl); @@ -8750,6 +8770,7 @@ convert_template_argument (tree parm, { if (in_decl && (complain & tf_error)) { + auto_diagnostic_group d; error ("constraint mismatch at argument %d in " "template parameter list for %qD", i + 1, in_decl); @@ -9132,6 +9153,7 @@ coerce_template_parms (tree parms, bad_nargs: if (complain & tf_error) { + auto_diagnostic_group d; if (variadic_p || default_p) { nparms -= variadic_p + default_p; @@ -9167,6 +9189,7 @@ coerce_template_parms (tree parms, if (PACK_EXPANSION_P (arg) && !template_parameter_pack_p (parm)) { + auto_diagnostic_group d; if (DECL_ALIAS_TEMPLATE_P (in_decl)) error_at (location_of (arg), "pack expansion argument for non-pack parameter " @@ -17344,6 +17367,7 @@ tsubst_qualified_id (tree qualified_id, tree args, { if (complain & tf_error) { + auto_diagnostic_group d; error ("dependent-name %qE is parsed as a non-type, but " "instantiation yields a type", qualified_id); inform (input_location, "say %<typename %E%> if a type is meant", qualified_id); @@ -20934,6 +20958,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (unq != function) { + auto_diagnostic_group d; char const *const msg = G_("%qD was not declared in this scope, " "and no declarations were found by " @@ -26366,6 +26391,7 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain, char *spaces = NULL; if (!(complain & tf_error)) return error_mark_node; + auto_diagnostic_group d; if (TYPE_P (target)) error ("ambiguous template instantiation for %q#T", target); else @@ -30804,6 +30830,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, { /* Be permissive with equivalent alias templates. */ tree u = get_underlying_template (tmpl); + auto_diagnostic_group d; diagnostic_t dk = (u == tmpl) ? DK_ERROR : DK_PEDWARN; bool complained = emit_diagnostic (dk, input_location, 0, @@ -30960,6 +30987,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, { if (complain & tf_warning_or_error) { + auto_diagnostic_group d; error ("class template argument deduction failed:"); perform_dguide_overload_resolution (cands, args, complain); if (elided) @@ -30977,6 +31005,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, if (complain & tf_warning_or_error) { // TODO: Pass down location from cp_finish_decl. + auto_diagnostic_group d; error ("class template argument deduction for %qT failed: " "explicit deduction guide selected in " "copy-list-initialization", type); @@ -30992,6 +31021,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, tree outer_targs, guides, this deduction might not be what the user intended. */ if (fndecl != error_mark_node && !any_dguides_p && (complain & tf_warning)) { + auto_diagnostic_group d; if ((!DECL_IN_SYSTEM_HEADER (fndecl) || global_dc->m_warn_system_headers) && warning (OPT_Wctad_maybe_unsupported, @@ -31119,6 +31149,7 @@ do_auto_deduction (tree type, tree init, tree auto_node, { if (complain & tf_warning_or_error) { + auto_diagnostic_group d; if (permerror (loc, "direct-list-initialization of " "%<auto%> requires exactly one element")) inform (loc, diff --git a/gcc/cp/search.cc b/gcc/cp/search.cc index 827f48e8604..60c30ecb881 100644 --- a/gcc/cp/search.cc +++ b/gcc/cp/search.cc @@ -1227,6 +1227,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type, { if (complain & tf_error) { + auto_diagnostic_group d; error ("request for member %qD is ambiguous", name); print_candidates (lfi.ambiguous); } diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index e58612660c9..d61e809ab80 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -2383,6 +2383,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope, { if (complain & tf_error) { + auto_diagnostic_group d; if (current_function_decl && DECL_STATIC_FUNCTION_P (current_function_decl)) error ("invalid use of member %qD in static member function", decl); @@ -4243,6 +4244,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use) { if (complain & tf_error) { + auto_diagnostic_group d; error ("%qD is not captured", decl); tree closure = LAMBDA_EXPR_CLOSURE (lambda_expr); if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE) @@ -4263,6 +4265,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use) { if (complain & tf_error) { + auto_diagnostic_group d; error (VAR_P (decl) ? G_("use of local variable with automatic storage from " "containing function") @@ -4498,6 +4501,7 @@ finish_id_expression_1 (tree id_expression, if (TREE_CODE (decl) == TREE_LIST) { /* Ambiguous reference to base members. */ + auto_diagnostic_group d; error ("request for member %qD is ambiguous in " "multiple inheritance lattice", id_expression); print_candidates (decl); @@ -4904,6 +4908,7 @@ finish_offsetof (tree object_ptr, tree expr, location_t loc) if (DECL_P (expr)) { + auto_diagnostic_group d; error ("cannot apply %<offsetof%> to member function %qD", expr); inform (DECL_SOURCE_LOCATION (expr), "declared here"); } @@ -6316,6 +6321,7 @@ omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp, return ret; if (!ambiguous.is_empty ()) { + auto_diagnostic_group d; const char *str = _("candidates are:"); unsigned int idx; tree udr; @@ -8388,6 +8394,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) && !type_dependent_expression_p (t) && !omp_mappable_type (TREE_TYPE (t))) { + auto_diagnostic_group d; error_at (OMP_CLAUSE_LOCATION (c), "array section does not have mappable type " "in %qs clause", @@ -8610,6 +8617,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) ? TREE_TYPE (TREE_TYPE (t)) : TREE_TYPE (t))) { + auto_diagnostic_group d; error_at (OMP_CLAUSE_LOCATION (c), "%qD does not have a mappable type in %qs clause", t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); @@ -8777,6 +8785,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } else if (!omp_mappable_type (TREE_TYPE (t))) { + auto_diagnostic_group d; error_at (OMP_CLAUSE_LOCATION (c), "%qD does not have a mappable type in %qs clause", t, cname); diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index 31ecbb1ac79..c3a38de4f48 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -5223,6 +5223,7 @@ check_abi_tag_redeclaration (const_tree decl, const_tree old, const_tree new_) if (new_ && TREE_CODE (TREE_VALUE (new_)) == TREE_LIST) new_ = TREE_VALUE (new_); bool err = false; + auto_diagnostic_group d; for (const_tree t = new_; t; t = TREE_CHAIN (t)) { tree str = TREE_VALUE (t); @@ -5276,6 +5277,7 @@ check_abi_tag_args (tree args, tree name) { if (!ISALPHA (c) && c != '_') { + auto_diagnostic_group d; error ("arguments to the %qE attribute must contain valid " "identifiers", name); inform (input_location, "%<%c%> is not a valid first " @@ -5289,6 +5291,7 @@ check_abi_tag_args (tree args, tree name) { if (!ISALNUM (c) && c != '_') { + auto_diagnostic_group d; error ("arguments to the %qE attribute must contain valid " "identifiers", name); inform (input_location, "%<%c%> is not a valid character " diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index f26b5b2a1f4..d4fc848bfa1 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -2365,6 +2365,7 @@ invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain) { if (DECL_P (expr)) { + auto_diagnostic_group d; error_at (loc, "invalid use of non-static member function %qD", expr); inform (DECL_SOURCE_LOCATION (expr), "declared here"); @@ -3309,6 +3310,7 @@ complain_about_unrecognized_member (tree access_path, tree name, { /* The guessed name isn't directly accessible, and no accessor member function could be found. */ + auto_diagnostic_group d; error_at (&rich_loc, "%q#T has no member named %qE;" " did you mean %q#D? (not accessible from this context)", @@ -3534,6 +3536,7 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, else { /* Look up the member. */ + auto_diagnostic_group d; access_failure_info afi; if (processing_template_decl) /* Even though this class member access expression is at this @@ -4504,6 +4507,7 @@ error_args_num (location_t loc, tree fndecl, bool too_many_p) { if (fndecl) { + auto_diagnostic_group d; if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE) { if (DECL_NAME (fndecl) == NULL_TREE @@ -4952,6 +4956,7 @@ warn_for_null_address (location_t location, tree op, tsubst_flags_t complain) STRIP_NOPS (cop); } + auto_diagnostic_group d; bool warned = false; if (TREE_CODE (cop) == ADDR_EXPR) { @@ -6106,6 +6111,7 @@ cp_build_binary_op (const op_location_t &location, { if (complain & tf_error) { + auto_diagnostic_group d; error_at (location, "comparing vectors with different " "element types"); inform (location, "operand types are %qT and %qT", @@ -6119,6 +6125,7 @@ cp_build_binary_op (const op_location_t &location, { if (complain & tf_error) { + auto_diagnostic_group d; error_at (location, "comparing vectors with different " "number of elements"); inform (location, "operand types are %qT and %qT", @@ -6964,6 +6971,7 @@ build_x_unary_op (location_t loc, enum tree_code code, cp_expr xarg, { if (complain & tf_error) { + auto_diagnostic_group d; error_at (loc, "invalid use of %qE to form a " "pointer-to-member-function", xarg.get_value ()); if (TREE_CODE (xarg) != OFFSET_REF) @@ -7498,10 +7506,13 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert, { /* Warn if the expression has boolean value. */ if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE - && (complain & tf_warning) - && warning_at (location, OPT_Wbool_operation, - "%<~%> on an expression of type %<bool%>")) - inform (location, "did you mean to use logical not (%<!%>)?"); + && (complain & tf_warning)) + { + auto_diagnostic_group d; + if (warning_at (location, OPT_Wbool_operation, + "%<~%> on an expression of type %<bool%>")) + inform (location, "did you mean to use logical not (%<!%>)?"); + } arg = cp_perform_integral_promotions (arg, complain); } else if (!noconvert && VECTOR_TYPE_P (TREE_TYPE (arg))) @@ -8723,6 +8734,7 @@ build_static_cast (location_t loc, tree type, tree oexpr, if (complain & tf_error) { + auto_diagnostic_group d; error_at (loc, "invalid %<static_cast%> from type %qT to type %qT", TREE_TYPE (expr), type); if ((TYPE_PTR_P (type) || TYPE_REF_P (type)) @@ -9682,15 +9694,19 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, rhs = decay_conversion (rhs, complain); if (rhs == error_mark_node) return error_mark_node; - rhs = stabilize_expr (rhs, &init); - newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain); - if (newrhs == error_mark_node) - { - if (complain & tf_error) - inform (loc, " in evaluation of %<%Q(%#T, %#T)%>", - modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs)); - return error_mark_node; - } + + { + auto_diagnostic_group d; + rhs = stabilize_expr (rhs, &init); + newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain); + if (newrhs == error_mark_node) + { + if (complain & tf_error) + inform (loc, " in evaluation of %<%Q(%#T, %#T)%>", + modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs)); + return error_mark_node; + } + } if (init) newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs); @@ -9970,6 +9986,7 @@ get_delta_difference (tree from, tree to, bool allow_inverse_p, bool c_cast_p, tsubst_flags_t complain) { + auto_diagnostic_group d; tree result; if (same_type_ignoring_top_level_qualifiers_p (from, to)) @@ -10384,6 +10401,8 @@ convert_for_assignment (tree type, tree rhs, { if (complain & tf_error) { + auto_diagnostic_group d; + /* If the right-hand side has unknown type, then it is an overloaded function. Call instantiate_type to get error messages. */ @@ -10406,7 +10425,6 @@ convert_for_assignment (tree type, tree rhs, (rhs_loc, has_loc ? &label : NULL, has_loc ? highlight_colors::percent_h : NULL); - auto_diagnostic_group d; switch (errtype) { @@ -11150,6 +11168,7 @@ check_return_expr (tree retval, bool *no_warning, bool *dangling) if (!retval && !is_auto (pattern)) { /* Give a helpful error message. */ + auto_diagnostic_group d; error ("return-statement with no value, in function returning %qT", pattern); inform (input_location, "only plain %<auto%> return type can be " diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc index 30a6fbe95c9..a05b14179b3 100644 --- a/gcc/cp/typeck2.cc +++ b/gcc/cp/typeck2.cc @@ -302,6 +302,7 @@ cxx_incomplete_type_diagnostic (location_t loc, const_tree value, if (TREE_CODE (type) == ERROR_MARK) return false; + auto_diagnostic_group d; if (value) { STRIP_ANY_LOCATION_WRAPPER (value);
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? -- >8 -- This patch goes through all .cc files in gcc/cp and adds in any auto_diagnostic_groups that seem to be missing by looking for any 'inform' calls that aren't grouped with their respective error/warning. Now with SARIF output support this seems to be a bit more important. The patch isn't complete; I've tried to also track helper functions used for diagnostics to group them, but some may have been missed. Additionally there are a few functions that are definitely missing groupings but I wasn't able to see an obvious way to add them without potentially grouping together unrelated messages. This list includes: - lazy_load_{binding,pendings} "during load of {binding,pendings} for" - cp_finish_decomp "in initialization of structured binding variable" - require_deduced_type "using __builtin_source_location" - convert_nontype_argument "in template argument for type %qT" - coerce_template_params "so any instantiation with a non-empty parameter pack" - tsubst_default_argument "when instantiating default argument" - invalid_nontype_parm_type_p "invalid template non-type parameter" gcc/cp/ChangeLog: * class.cc (add_method): Add missing auto_diagnostic_group. (handle_using_decl): Likewise. (maybe_warn_about_overly_private_class): Likewise. (check_field_decl): Likewise. (check_field_decls): Likewise. (resolve_address_of_overloaded_function): Likewise. (note_name_declared_in_class): Likewise. * constraint.cc (associate_classtype_constraints): Likewise. (diagnose_trait_expr): Clean up whitespace. * coroutines.cc (find_coro_traits_template_decl): Add missing auto_diagnostic_group. (coro_promise_type_found_p): Likewise. (coro_diagnose_throwing_fn): Likewise. * cvt.cc (build_expr_type_conversion): Likewise. * decl.cc (validate_constexpr_redeclaration): Likewise. (duplicate_function_template_decls): Likewise. (duplicate_decls): Likewise. (lookup_label_1): Likewise. (check_previous_goto_1): Likewise. (check_goto_1): Likewise. (make_typename_type): Likewise. (make_unbound_class_template): Likewise. (check_tag_decl): Likewise. (start_decl): Likewise. (maybe_commonize_var): Likewise. (check_for_uninitialized_const_var): Likewise. (reshape_init_class): Likewise. (check_initializer): Likewise. (cp_finish_decl): Likewise. (find_decomp_class_base): Likewise. (cp_finish_decomp): Likewise. (expand_static_init): Likewise. (grokfndecl): Likewise. (grokdeclarator): Likewise. (check_elaborated_type_specifier): Likewise. (lookup_and_check_tag): Likewise. (xref_tag): Likewise. (cxx_simulate_enum_decl): Likewise. (finish_function): Likewise. * decl2.cc (check_classfn): Likewise. (record_mangling): Likewise. (mark_used): Likewise. * error.cc (qualified_name_lookup_error): Likewise. * except.cc (build_throw): Likewise. * init.cc (get_nsdmi): Likewise. (diagnose_uninitialized_cst_or_ref_member_1): Likewise. (warn_placement_new_too_small): Likewise. (build_new_1): Likewise. (build_vec_delete_1): Likewise. (build_delete): Likewise. * lambda.cc (add_capture): Likewise. (add_default_capture): Likewise. * lex.cc (unqualified_fn_lookup_error): Likewise. * method.cc (synthesize_method): Likewise. (defaulted_late_check): Likewise. * module.cc (trees_in::is_matching_decl): Likewise. (trees_in::read_enum_def): Likewise. (module_state::check_not_purview): Likewise. (module_state::deferred_macro): Likewise. (module_state::read_config): Likewise. (module_state::check_read): Likewise. (declare_module): Likewise. (init_modules): Likewise. * name-lookup.cc (diagnose_name_conflict): Likewise. (lookup_using_decl): Likewise. (set_decl_namespace): Likewise. (finish_using_directive): Likewise. (push_namespace): Likewise. (add_imported_namespace): Likewise. * parser.cc (cp_parser_check_for_definition_in_return_type): Likewise. (cp_parser_userdef_numeric_literal): Likewise. (cp_parser_nested_name_specifier_opt): Likewise. (cp_parser_new_expression): Likewise. (cp_parser_binary_expression): Likewise. (cp_parser_lambda_introducer): Likewise. (cp_parser_module_declaration): Likewise. (cp_parser_import_declaration): Likewise, removing gotos to support this. (cp_parser_declaration): Add missing auto_diagnostic_group. (cp_parser_decl_specifier_seq): Likewise. (cp_parser_template_id): Likewise. (cp_parser_template_name): Likewise. (cp_parser_explicit_specialization): Likewise. (cp_parser_placeholder_type_specifier): Likewise. (cp_parser_elaborated_type_specifier): Likewise. (cp_parser_enum_specifier): Likewise. (cp_parser_asm_definition): Likewise. (cp_parser_init_declarator): Likewise. (cp_parser_direct_declarator): Likewise. (cp_parser_class_head): Likewise. (cp_parser_member_declaration): Likewise. (cp_parser_lookup_name): Likewise. (cp_parser_explicit_template_declaration): Likewise. (cp_parser_check_class_key): Likewise. * pt.cc (maybe_process_partial_specialization): Likewise. (determine_specialization): Likewise. (check_for_bare_parameter_packs): Likewise. (check_template_shadow): Likewise. (process_partial_specialization): Likewise. (push_template_decl): Likewise. (redeclare_class_template): Likewise. (convert_nontype_argument_function): Likewise. (check_valid_ptrmem_cst_expr): Likewise. (convert_nontype_argument): Likewise. (convert_template_argument): Likewise. (coerce_template_parms): Likewise. (tsubst_qualified_id): Likewise. (tsubst_expr): Likewise. (most_specialized_partial_spec): Likewise. (do_class_deduction): Likewise. (do_auto_deduction): Likewise. * search.cc (lookup_member): Likewise. * semantics.cc (finish_non_static_data_member): Likewise. (process_outer_var_ref): Likewise. (finish_id_expression_1): Likewise. (finish_offsetof): Likewise. (omp_reduction_lookup): Likewise. (finish_omp_clauses): Likewise. * tree.cc (check_abi_tag_redeclaration): Likewise. (check_abi_tag_args): Likewise. * typeck.cc (invalid_nonstatic_memfn_p): Likewise. (complain_about_unrecognized_member): Likewise. (finish_class_member_access_expr): Likewise. (error_args_num): Likewise. (warn_for_null_address): Likewise. (cp_build_binary_op): Likewise. (build_x_unary_op): Likewise. (cp_build_unary_op): Likewise. (build_static_cast): Likewise. (cp_build_modify_expr): Likewise. (get_delta_difference): Likewise. (convert_for_assignment): Widen scope of auto_diagnostic_group. (check_return_expr): Add missing auto_diagnostic_group. * typeck2.cc (cxx_incomplete_type_diagnostic): Likewise. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> --- gcc/cp/class.cc | 12 +++++ gcc/cp/constraint.cc | 21 +++++---- gcc/cp/coroutines.cc | 3 ++ gcc/cp/cvt.cc | 1 + gcc/cp/decl.cc | 59 +++++++++++++++++++++-- gcc/cp/decl2.cc | 3 ++ gcc/cp/error.cc | 2 + gcc/cp/except.cc | 1 + gcc/cp/init.cc | 8 ++++ gcc/cp/lambda.cc | 3 ++ gcc/cp/lex.cc | 1 + gcc/cp/method.cc | 3 ++ gcc/cp/module.cc | 8 ++++ gcc/cp/name-lookup.cc | 7 +++ gcc/cp/parser.cc | 107 ++++++++++++++++++++++++++++-------------- gcc/cp/pt.cc | 65 ++++++++++++++++++------- gcc/cp/search.cc | 1 + gcc/cp/semantics.cc | 9 ++++ gcc/cp/tree.cc | 3 ++ gcc/cp/typeck.cc | 47 +++++++++++++------ gcc/cp/typeck2.cc | 1 + 21 files changed, 286 insertions(+), 79 deletions(-)