Age | Commit message (Collapse) | Author | Files | Lines |
|
Currently the streaming code uses TREE_CONSTANT to determine whether an
entity will have a definition that is interesting to stream out. This
is not sufficient, however; we also need to write the definition of
references, since although not TREE_CONSTANT they can still be usable in
constant expressions.
As such this patch uses the existing decl_maybe_constant_var function
which correctly handles this case.
gcc/cp/ChangeLog:
* module.cc (has_definition): Use decl_maybe_constant_var
instead of TREE_CONSTANT.
gcc/testsuite/ChangeLog:
* g++.dg/modules/cexpr-5_a.C: New test.
* g++.dg/modules/cexpr-5_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
My last fix for this issue (PR c++/114947, r15-810) didn't go far
enough; I had assumed that the issue where we lost track of partial
specialisations we would need to walk again later was limited to
partitions (where we always re-walk all specialisations), but the linked
PR is the same cause but for header units, and it is possible to
construct test cases exposing the same bug just for normal modules.
As such this patch just unconditionally ensures that whenever we modify
DECL_TEMPLATE_SPECIALIZATIONS we also track any partial specialisations
that might have added.
Also clean up a couple of comments and assertions to make expected state
more obvious when processing these specs.
PR c++/116496
gcc/cp/ChangeLog:
* module.cc (trees_in::decl_value): Don't call
set_defining_module_for_partial_spec here.
(depset::hash::add_partial_entities): Clarity assertions.
* pt.cc (add_mergeable_specialization): Always call
set_defining_module_for_partial_spec when adding a partial spec.
gcc/testsuite/ChangeLog:
* g++.dg/modules/partial-5_a.C: New test.
* g++.dg/modules/partial-5_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
Rename diagnostic_context's "printer" field to "m_printer",
for consistency with other fields, and to highlight places
where we currently use this, to help assess feasibility
of supporting multiple output sinks (PR other/116613).
No functional change intended.
gcc/ChangeLog:
PR other/116613
* attribs.cc (decls_mismatched_attributes): Rename
diagnostic_context's "printer" field to "m_printer".
(attr_access::array_as_string): Likewise.
* diagnostic-format-json.cc
(json_output_format::on_report_diagnostic): Likewise.
(diagnostic_output_format_init_json): Likewise.
* diagnostic-format-sarif.cc
(sarif_result::on_nested_diagnostic): Likewise.
(sarif_ice_notification): Likewise.
(sarif_builder::on_report_diagnostic): Likewise.
(sarif_builder::make_result_object): Likewise.
(sarif_builder::make_location_object): Likewise.
(sarif_builder::make_message_object_for_diagram): Likewise.
(diagnostic_output_format_init_sarif): Likewise.
* diagnostic-format-text.cc
(diagnostic_text_output_format::~diagnostic_text_output_format):
Likewise.
(diagnostic_text_output_format::on_report_diagnostic): Likewise.
(diagnostic_text_output_format::on_diagram): Likewise.
(diagnostic_text_output_format::print_any_cwe): Likewise.
(diagnostic_text_output_format::print_any_rules): Likewise.
(diagnostic_text_output_format::print_option_information):
Likewise.
* diagnostic-format.h (diagnostic_output_format::get_printer):
New.
* diagnostic-global-context.cc (verbatim): Rename
diagnostic_context's "printer" field to "m_printer".
* diagnostic-path.cc (path_label::get_text): Likewise.
(print_path_summary_as_text): Likewise.
(diagnostic_context::print_path): Likewise.
(selftest::test_empty_path): Likewise.
(selftest::test_intraprocedural_path): Likewise.
(selftest::test_interprocedural_path_1): Likewise.
(selftest::test_interprocedural_path_2): Likewise.
(selftest::test_recursion): Likewise.
(selftest::test_control_flow_1): Likewise.
(selftest::test_control_flow_2): Likewise.
(selftest::test_control_flow_3): Likewise.
(assert_cfg_edge_path_streq): Likewise.
(selftest::test_control_flow_5): Likewise.
(selftest::test_control_flow_6): Likewise.
* diagnostic-show-locus.cc (layout::layout): Likewise.
(selftest::test_layout_x_offset_display_utf8): Likewise.
(selftest::test_layout_x_offset_display_tab): Likewise.
(selftest::test_diagnostic_show_locus_unknown_location): Likewise.
(selftest::test_one_liner_simple_caret): Likewise.
(selftest::test_one_liner_no_column): Likewise.
(selftest::test_one_liner_caret_and_range): Likewise.
(selftest::test_one_liner_multiple_carets_and_ranges): Likewise.
(selftest::test_one_liner_fixit_insert_before): Likewise.
(selftest::test_one_liner_fixit_insert_after): Likewise.
(selftest::test_one_liner_fixit_remove): Likewise.
(selftest::test_one_liner_fixit_replace): Likewise.
(selftest::test_one_liner_fixit_replace_non_equal_range):
Likewise.
(selftest::test_one_liner_fixit_replace_equal_secondary_range):
Likewise.
(selftest::test_one_liner_fixit_validation_adhoc_locations):
Likewise.
(selftest::test_one_liner_many_fixits_1): Likewise.
(selftest::test_one_liner_many_fixits_2): Likewise.
(selftest::test_one_liner_labels): Likewise.
(selftest::test_one_liner_simple_caret_utf8): Likewise.
(selftest::test_one_liner_caret_and_range_utf8): Likewise.
(selftest::test_one_liner_multiple_carets_and_ranges_utf8):
Likewise.
(selftest::test_one_liner_fixit_insert_before_utf8): Likewise.
(selftest::test_one_liner_fixit_insert_after_utf8): Likewise.
(selftest::test_one_liner_fixit_remove_utf8): Likewise.
(selftest::test_one_liner_fixit_replace_utf8): Likewise.
(selftest::test_one_liner_fixit_replace_non_equal_range_utf8):
Likewise.
(selftest::test_one_liner_fixit_replace_equal_secondary_range_utf8):
Likewise.
(selftest::test_one_liner_fixit_validation_adhoc_locations_utf8):
Likewise.
(selftest::test_one_liner_many_fixits_1_utf8): Likewise.
(selftest::test_one_liner_many_fixits_2_utf8): Likewise.
(selftest::test_one_liner_labels_utf8): Likewise.
(selftest::test_one_liner_colorized_utf8): Likewise.
(selftest::test_add_location_if_nearby): Likewise.
(selftest::test_diagnostic_show_locus_fixit_lines): Likewise.
(selftest::test_overlapped_fixit_printing): Likewise.
(selftest::test_overlapped_fixit_printing_utf8): Likewise.
(selftest::test_overlapped_fixit_printing_2): Likewise.
(selftest::test_fixit_insert_containing_newline): Likewise.
(selftest::test_fixit_insert_containing_newline_2): Likewise.
(selftest::test_fixit_replace_containing_newline): Likewise.
(selftest::test_fixit_deletion_affecting_newline): Likewise.
(selftest::test_tab_expansion): Likewise.
(selftest::test_escaping_bytes_1): Likewise.
(selftest::test_escaping_bytes_2): Likewise.
(selftest::test_line_numbers_multiline_range): Likewise.
* diagnostic.cc (file_name_as_prefix): Likewise.
(diagnostic_set_caret_max_width): Likewise.
(diagnostic_context::initialize): Likewise.
(diagnostic_context::color_init): Likewise.
(diagnostic_context::urls_init): Likewise.
(diagnostic_context::finish): Likewise.
(diagnostic_context::get_location_text): Likewise.
(diagnostic_build_prefix): Likewise.
(diagnostic_context::report_current_module): Likewise.
(default_diagnostic_starter): Likewise.
(default_diagnostic_start_span_fn): Likewise.
(default_diagnostic_finalizer): Likewise.
(diagnostic_context::report_diagnostic): Likewise.
(diagnostic_append_note): Likewise.
(diagnostic_context::error_recursion): Likewise.
(fancy_abort): Likewise.
* diagnostic.h (diagnostic_context::set_show_highlight_colors):
Likewise.
(diagnostic_context::printer): Rename to...
(diagnostic_context::m_printer): ...this.
(diagnostic_format_decoder): Rename diagnostic_context's "printer"
field to "m_printer".
(diagnostic_prefixing_rule): Likewise.
(diagnostic_ready_p): Likewise.
* gimple-ssa-warn-access.cc (pass_waccess::maybe_warn_memmodel):
Likewise.
* langhooks.cc (lhd_print_error_function): Likewise.
* lto-wrapper.cc (print_lto_docs_link): Likewise.
* opts-global.cc (init_options_once): Likewise.
* opts.cc (common_handle_option): Likewise.
* simple-diagnostic-path.cc (simple_diagnostic_path_cc_tests):
Likewise.
* text-art/dump.h (dump_to_file<T>): Likewise.
* toplev.cc (announce_function): Likewise.
(toplev::main): Likewise.
* tree-diagnostic.cc (default_tree_diagnostic_starter): Likewise.
* tree.cc (escaped_string::escape): Likewise.
(selftest::test_escaped_strings): Likewise.
gcc/ada/ChangeLog:
PR other/116613
* gcc-interface/misc.cc (internal_error_function): Rename
diagnostic_context's "printer" field to "m_printer".
gcc/analyzer/ChangeLog:
PR other/116613
* access-diagram.cc (access_range::dump): Rename
diagnostic_context's "printer" field to "m_printer".
* analyzer-language.cc (on_finish_translation_unit): Likewise.
* analyzer.cc (make_label_text): Likewise.
(make_label_text_n): Likewise.
* call-details.cc (call_details::dump): Likewise.
* call-summary.cc (call_summary::dump): Likewise.
(call_summary_replay::dump): Likewise.
* checker-event.cc (checker_event::debug): Likewise.
* constraint-manager.cc (range::dump): Likewise.
(bounded_range::dump): Likewise.
(bounded_ranges::dump): Likewise.
(constraint_manager::dump): Likewise.
* diagnostic-manager.cc
(diagnostic_manager::emit_saved_diagnostic): Likewise.
* engine.cc (exploded_node::dump): Likewise.
(exploded_path::dump): Likewise.
(run_checkers): Likewise.
* kf-analyzer.cc (kf_analyzer_dump_escaped::impl_call_pre):
Likewise.
* pending-diagnostic.cc (evdesc::event_desc::formatted_print):
Likewise.
* program-point.cc (function_point::print_source_line): Likewise.
(program_point::dump): Likewise.
* program-state.cc (extrinsic_state::dump_to_file): Likewise.
(sm_state_map::dump): Likewise.
(program_state::dump_to_file): Likewise.
* ranges.cc (symbolic_byte_offset::dump): Likewise.
(symbolic_byte_range::dump): Likewise.
* region-model-reachability.cc (reachable_regions::dump): Likewise.
* region-model.cc (region_to_value_map::dump): Likewise.
(region_model::dump): Likewise.
(model_merger::dump): Likewise.
* region.cc (region_offset::dump): Likewise.
(region::dump): Likewise.
* sm-malloc.cc (deallocator_set::dump): Likewise.
(sufficiently_similar_p): Likewise.
* store.cc (uncertainty_t::dump): Likewise.
(binding_key::dump): Likewise.
(binding_map::dump): Likewise.
(binding_cluster::dump): Likewise.
(store::dump): Likewise.
* supergraph.cc (supergraph::dump_dot_to_file): Likewise.
(superedge::dump): Likewise.
* svalue.cc (svalue::dump): Likewise.
gcc/c-family/ChangeLog:
PR other/116613
* c-format.cc (selftest::test_type_mismatch_range_labels): Rename
diagnostic_context's "printer" field to "m_printer".
(selftest::test_type_mismatch_range_labels): Likewise.
* c-opts.cc (c_diagnostic_finalizer): Likewise.
gcc/c/ChangeLog:
PR other/116613
* c-objc-common.cc (c_initialize_diagnostics): Rename
diagnostic_context's "printer" field to "m_printer".
gcc/cp/ChangeLog:
PR other/116613
* error.cc (cxx_initialize_diagnostics): Rename
diagnostic_context's "printer" field to "m_printer".
(cxx_print_error_function): Likewise.
(cp_diagnostic_starter): Likewise.
(cp_print_error_function): Likewise.
(print_instantiation_full_context): Likewise.
(print_instantiation_partial_context_line): Likewise.
(maybe_print_constexpr_context): Likewise.
(print_location): Likewise.
(print_constrained_decl_info): Likewise.
(print_concept_check_info): Likewise.
(print_constraint_context_head): Likewise.
(print_requires_expression_info): Likewise.
* module.cc (noisy_p): Likewise.
gcc/d/ChangeLog:
PR other/116613
* d-diagnostic.cc (d_diagnostic_report_diagnostic): Rename
diagnostic_context's "printer" field to "m_printer".
gcc/fortran/ChangeLog:
PR other/116613
* error.cc (gfc_clear_pp_buffer): Rename diagnostic_context's
"printer" field to "m_printer".
(gfc_warning): Likewise.
(gfc_diagnostic_build_kind_prefix): Likewise.
(gfc_diagnostic_build_locus_prefix): Likewise.
(gfc_diagnostic_starter): Likewise.
(gfc_diagnostic_starter): Likewise.
(gfc_diagnostic_start_span): Likewise.
(gfc_diagnostic_finalizer): Likewise.
(gfc_warning_check): Likewise.
(gfc_error_opt): Likewise.
(gfc_error_check): Likewise.
gcc/jit/ChangeLog:
PR other/116613
* jit-playback.cc (add_diagnostic): Rename diagnostic_context's
"printer" field to "m_printer".
gcc/testsuite/ChangeLog:
PR other/116613
* gcc.dg/plugin/analyzer_cpython_plugin.c (dump_refcnt_info):
Update for renaming of field "printer" to "m_printer".
* gcc.dg/plugin/diagnostic_group_plugin.c
(test_diagnostic_starter): Likewise.
(test_diagnostic_start_span_fn): Likewise.
(test_output_format::on_begin_group): Likewise.
(test_output_format::on_end_group): Likewise.
* gcc.dg/plugin/diagnostic_plugin_test_paths.c: Likewise.
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
(custom_diagnostic_finalizer): Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
|
|
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>
|
|
After importing a header unit we learn about and setup any header
modules that we transitively depend on. However, this causes
'set_filename' to fail an assertion if we then come across this header
as an #include and attempt to translate it into a module. We still need
to do this translation so that libcpp learns that this is a header unit,
but we shouldn't error just because we've already seen it as an import.
Instead this patch merely checks and errors to handle the case of a
broken mapper implementation which supplies a different CMI path from
the one we already got.
As a drive-by fix, also make failing to find the CMI for a module be a
fatal error: any further errors in the TU are unlikely to be helpful.
PR c++/99243
gcc/cp/ChangeLog:
* module.cc (module_state::set_filename): Handle repeated calls
to 'set_filename' as long as the CMI path matches.
(maybe_translate_include): Adjust comment.
gcc/testsuite/ChangeLog:
* g++.dg/modules/map-2.C: Prune additional fatal error message.
* g++.dg/modules/inc-xlate-4_a.H: New test.
* g++.dg/modules/inc-xlate-4_b.H: New test.
* g++.dg/modules/inc-xlate-4_c.H: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
Currently the handling of include translation is confusing to read,
using a tri-state integer without much clarity on what different states
mean. This patch cleans this up to use explicit enumerators indicating
the different possible states instead, and fixes a bug where the option
'-flang-info-include-translate' ended being accidentally unusable.
PR c++/110980
gcc/cp/ChangeLog:
* module.cc (maybe_translate_include): Clean up.
gcc/testsuite/ChangeLog:
* g++.dg/modules/inc-xlate-2_a.H: New test.
* g++.dg/modules/inc-xlate-2_b.H: New test.
* g++.dg/modules/inc-xlate-3.h: New test.
* g++.dg/modules/inc-xlate-3_a.H: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
It was pointed out to me that the current error referencing an internal
linkage entity reads almost like an ICE message, with the message
finishing with the unhelpful:
m.cpp:1:8: error: failed to write compiled module: Bad file data
1 | export module M;
| ^~~~~~
Similarly, whenever we decide not to emit a module CMI due to other
errors we currently emit the following message:
m.cpp:1:8: warning: not writing module âMâ due to errors
1 | export module M;
| ^~~~~~
Neither of these messages really add anything useful; users already
understand that when an error is reported then the normal outputs will
not be created, so these messages are just noise.
There is one case we still need this latter message, however; when an
error in a template has been silenced with '-Wno-template-body' we still
don't want to write a module CMI, so emit an error now instead.
This patch also removes a number of dg-prune-output directives in the
testsuite that are no longer needed with this change.
gcc/cp/ChangeLog:
* module.cc (module_state::write_begin): Return a boolean to
indicate errors rather than just doing set_error().
(finish_module_processing): Prevent emission of unnecessary
errors; only indicate module writing occurred if write_begin
succeeds.
gcc/testsuite/ChangeLog:
* g++.dg/modules/export-1.C: Remove message.
* g++.dg/modules/internal-1.C: Remove message.
* g++.dg/modules/ambig-2_b.C: Remove unnecessary pruning.
* g++.dg/modules/atom-decl-2.C: Likewise.
* g++.dg/modules/atom-pragma-3.C: Likewise.
* g++.dg/modules/atom-preamble-2_f.C: Likewise.
* g++.dg/modules/block-decl-2.C: Likewise.
* g++.dg/modules/dir-only-4.C: Likewise.
* g++.dg/modules/enum-12.C: Likewise.
* g++.dg/modules/exp-xlate-1_b.C: Likewise.
* g++.dg/modules/export-3.C: Likewise.
* g++.dg/modules/friend-3.C: Likewise.
* g++.dg/modules/friend-5_b.C: Likewise.
* g++.dg/modules/inc-xlate-1_e.C: Likewise.
* g++.dg/modules/linkage-2.C: Likewise.
* g++.dg/modules/local-extern-1.C: Likewise.
* g++.dg/modules/main-1.C: Likewise.
* g++.dg/modules/map-2.C: Likewise.
* g++.dg/modules/mod-decl-1.C: Likewise.
* g++.dg/modules/mod-decl-3.C: Likewise.
* g++.dg/modules/pr99174.H: Likewise.
* g++.dg/modules/pr99468.H: Likewise.
* g++.dg/modules/token-1.C: Likewise.
* g++.dg/modules/token-3.C: Likewise.
* g++.dg/modules/token-4.C: Likewise.
* g++.dg/modules/token-5.C: Likewise.
* g++.dg/modules/using-10.C: Likewise.
* g++.dg/modules/using-12.C: Likewise.
* g++.dg/modules/using-3.C: Likewise.
* g++.dg/modules/using-9.C: Likewise.
* g++.dg/modules/using-enum-2.C: Likewise.
* g++.dg/modules/permissive-error-1.C: New test.
* g++.dg/modules/permissive-error-2.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
[PR115020]
The error in the linked PR is caused because 'DECL_THIS_STATIC' is true
for the static member function, causing the streaming code to assume
that this is an internal linkage GM entity that needs to be explicitly
streamed, which then on read-in gets marked as a vague linkage function
(despite being non-inline) causing import_export_decl to complain.
However, I don't see any reason why we should care about this:
definitions in the GMF should just be emitted as per usual regardless of
whether they're internal-linkage or not. Actually the only thing we
care about here are header modules, since they have no TU to write
definitions into. As such this patch removes these conditions from
'has_definition' and updates some comments to clarify.
PR c++/115020
gcc/cp/ChangeLog:
* module.cc (has_definition): Only force writing definitions for
header_module_p.
gcc/testsuite/ChangeLog:
* g++.dg/modules/pr115020_a.C: New test.
* g++.dg/modules/pr115020_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
Currently we implement [temp.deduct.guide] p1 by forcing all deduction
guides to be considered as exported. However this is not sufficient:
for transitive non-exported imports we will still hide the deduction
guide from name lookup, causing errors.
This patch instead adjusts name lookup to have a new ANY_REACHABLE flag
to allow for this case. Currently this is only used by deduction guides
but there are some other circumstances where this may be useful in the
future (e.g. finding existing temploid friends).
PR c++/116403
gcc/cp/ChangeLog:
* pt.cc (deduction_guides_for): Use ANY_REACHABLE for lookup of
deduction guides.
* module.cc (depset::hash::add_deduction_guides): Likewise.
(module_state::write_cluster): No longer override deduction
guides as exported.
* name-lookup.cc (name_lookup::search_namespace_only): Ignore
visibility when LOOK_want::ANY_REACHABLE is specified.
(check_module_override): Ignore visibility when checking for
ambiguating deduction guides.
* name-lookup.h (LOOK_want): New flag 'ANY_REACHABLE'.
gcc/testsuite/ChangeLog:
* g++.dg/modules/dguide-4_a.C: New test.
* g++.dg/modules/dguide-4_b.C: New test.
* g++.dg/modules/dguide-4_c.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
When reading an NTTP we call get_template_parm_object which delegates
setting of DECL_INITIAL to the general cp_finish_decl procedure, which
calls check_initializer to validate and record it.
Apart from being unnecessary (it must have already been validated by the
writing module), this also causes errors in cases like the linked PR, as
validating may end up needing to call lazy_load_pendings to determine
any specialisations that may exist which violates assumptions of the
modules streaming code.
This patch works around the issue by adding a flag to
get_template_parm_object to disable these checks when not needed.
PR c++/116382
gcc/cp/ChangeLog:
* cp-tree.h (get_template_parm_object): Add check_init param.
* module.cc (trees_in::tree_node): Pass check_init=false when
building NTTPs.
* pt.cc (get_template_parm_object): Prevent cp_finish_decl from
validating the initializer when check_init=false.
gcc/testsuite/ChangeLog:
* g++.dg/modules/tpl-nttp-1_a.C: New test.
* g++.dg/modules/tpl-nttp-1_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
We need to use the DECL_TEMPLATE_INSTANTIATIONS property to find
reachable specialisations from a template to ensure that any GM
specialisations are properly marked as reachable.
Currently the modules code uses the decl when rebuilding this property,
but this is not always correct; it appears that for type specialisations
we need to use the TREE_TYPE of the decl instead so that the
specialisation is correctly found. This patch makes the required
adjustments.
PR c++/116364
gcc/cp/ChangeLog:
* cp-tree.h (get_mergeable_specialization_flags): Adjust
signature.
* module.cc (trees_out::decl_value): Indicate whether this is a
type or decl specialisation.
* pt.cc (get_mergeable_specialization_flags): Match against the
type of a non-decl specialisation.
(add_mergeable_specialization): Use the already calculated spec
instead of always adding decl to DECL_TEMPLATE_INSTANTIATIONS.
gcc/testsuite/ChangeLog:
* g++.dg/modules/tpl-spec-9_a.C: New test.
* g++.dg/modules/tpl-spec-9_b.C: New test.
* g++.dg/modules/tpl-spec-9_c.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
While stepping through some code I noticed that we do some extra work
(finding the originating module decl, stripping the template, and
inspecting the attached-ness) for every declaration taken from a header
unit. This doesn't seem necessary though since no declaration in a
header unit can be attached to anything but the global module, so we can
just assume that global_p will be true.
This was the original behaviour before I removed this assumption while
refactoring for r15-2807-gc592310d5275e0.
gcc/cp/ChangeLog:
* module.cc (module_state::read_cluster): Assume header module
declarations will require GM merging.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
Currently name lookup generally seems to assume that all entities
declared within a named module (partition) are attached to said module,
which is not true for GM entities (e.g. via extern "C++"), and causes
issues with deduplication.
This patch fixes the issue by ensuring that module attachment of a
declaration is consistently used to handling merging. Handling this
exposes some issues with deduplicating temploid friends; to resolve this
we always create the BINDING_SLOT_PARTITION slot so that we have
somewhere to place attached names (from any module).
This doesn't yet completely handle issues with allowing otherwise
conflicting temploid friends from different modules to co-exist in the
same module if neither are reachable from the other via name lookup.
PR c++/114950
gcc/cp/ChangeLog:
* module.cc (trees_out::decl_value): Stream bit indicating
imported temploid friends early.
(trees_in::decl_value): Use this bit with key_mergeable.
(trees_in::key_mergeable): Allow merging attached declarations
if they're imported temploid friends (which must be namespace
scope).
(module_state::read_cluster): Check for GM entities that may
require merging even when importing from partitions.
* name-lookup.cc (enum binding_slots): Adjust comment.
(get_fixed_binding_slot): Always create partition slot.
(name_lookup::search_namespace_only): Support binding vectors
with both partition and GM entities to dedup.
(walk_module_binding): Likewise.
(name_lookup::adl_namespace_fns): Likewise.
(set_module_binding): Likewise.
(check_module_override): Use attachment of the decl when
checking overrides rather than named_module_p.
(lookup_imported_hidden_friend): Use partition slot for finding
mergeable template bindings.
* name-lookup.h (set_module_binding): Split mod_glob_flag
parameter into separate global_p and partition_p params.
gcc/testsuite/ChangeLog:
* g++.dg/modules/tpl-friend-13_e.C: Adjust error message.
* g++.dg/modules/ambig-2_a.C: New test.
* g++.dg/modules/ambig-2_b.C: New test.
* g++.dg/modules/part-9_a.C: New test.
* g++.dg/modules/part-9_b.C: New test.
* g++.dg/modules/part-9_c.C: New test.
* g++.dg/modules/tpl-friend-15.h: New test.
* g++.dg/modules/tpl-friend-15_a.C: New test.
* g++.dg/modules/tpl-friend-15_b.C: New test.
* g++.dg/modules/tpl-friend-15_c.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
This error message reads to me the wrong way around, particularly in the
context of other errors. Updated so that the ellipsis connect.
gcc/cp/ChangeLog:
* module.cc (trees_in::read_enum_def): Clarify error.
gcc/testsuite/ChangeLog:
* g++.dg/modules/enum-bad-1_b.C: Update error message.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
Deduction guides are represented as 'normal' functions currently, and
have no special handling in modules. However, this causes some issues;
by [temp.deduct.guide] a deduction guide is not found by normal name
lookup and instead all reachable deduction guides for a class template
should be considered, but this does not happen currently.
To solve this, this patch ensures that all deduction guides are
considered exported to ensure that they are always visible to importers
if they are reachable. Another alternative here would be to add a new
kind of "all reachable" flag to name lookup, but that is complicated by
some difficulties in handling GM entities; this may be a better way to
go if more kinds of entities end up needing this handling, however.
Another issue here is that because deduction guides are "unrelated"
functions, they will usually get discarded from the GMF, so this patch
ensures that when finding dependencies, GMF deduction guides will also
have bindings created. We do this in find_dependencies so that we don't
unnecessarily create bindings for GMF deduction guides that are never
reached; for consistency we do this for *all* deduction guides, not just
GM ones. We also make sure that the opposite (a deduction guide being
the only purview reference to a GMF template) correctly marks it as
reachable.
Finally, when merging deduction guides from multiple modules, the name
lookup code may now return two-dimensional overload sets, so update
callers to match.
As a small drive-by improvement this patch also updates the error pretty
printing code to add a space before the '->' when printing a deduction
guide, so we get 'S(int) -> S<int>' instead of 'S(int)-> S<int>'.
PR c++/115231
gcc/cp/ChangeLog:
* error.cc (dump_function_decl): Add a space before '->' when
printing deduction guides.
* module.cc (depset::hash::add_binding_entity): Don't create
bindings for guides here, only mark dependencies.
(depset::hash::add_deduction_guides): New.
(depset::hash::find_dependencies): Add deduction guide
dependencies for a class template.
(module_state::write_cluster): Always consider deduction guides
as exported.
* pt.cc (deduction_guides_for): Use 'lkp_iterator' instead of
'ovl_iterator'.
gcc/testsuite/ChangeLog:
* g++.dg/modules/dguide-1_a.C: New test.
* g++.dg/modules/dguide-1_b.C: New test.
* g++.dg/modules/dguide-2_a.C: New test.
* g++.dg/modules/dguide-2_b.C: New test.
* g++.dg/modules/dguide-3_a.C: New test.
* g++.dg/modules/dguide-3_b.C: New test.
* g++.dg/modules/dguide-3_c.C: New test.
* g++.dg/modules/dguide-3_d.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
In recent versions of GCC we've been diagnosing more and more kinds of
errors inside a template ahead of time. This is a largely good thing
because it catches bugs, typos, dead code etc sooner.
But if the template never gets instantiated then such errors are harmless
and can be inconvenient to work around if say the code in question is
third party and in maintenance mode. So it'd be handy to be able to
prevent these template errors from rendering the entire TU uncompilable.
(Note that such code is "ill-formed no diagnostic required" according
the standard.)
To that end this patch turns any errors issued within a template into
permerrors associated with a new -Wtemplate-body flag so that they can
be downgraded via e.g. -fpermissive or -Wno-error=template-body. If
the template containing a downgraded error later needs to be instantiated,
we'll issue an error then. But if the template never gets instantiated
then the downgraded error won't affect validity of the rest of the TU.
This is implemented via a diagnostic hook that gets called for each
diagnostic, and which adjusts an error diagnostic appropriately if we
detect it's occurring from a template context, and additionally flags
the template as erroneous.
For example the new testcase permissive-error1a.C gives:
gcc/testsuite/g++.dg/template/permissive-error1a.C: In function 'void f()':
gcc/testsuite/g++.dg/template/permissive-error1a.C:7:5: warning: increment of read-only variable 'n' [-Wtemplate-body]
7 | ++n;
| ^
...
gcc/testsuite/g++.dg/template/permissive-error1a.C: In instantiation of 'void f() [with T = int]':
gcc/testsuite/g++.dg/template/permissive-error1a.C:26:9: required from here
26 | f<int>();
| ~~~~~~^~
gcc/testsuite/g++.dg/template/permissive-error1a.C:5:6: error: instantiating erroneous template
5 | void f() {
| ^
gcc/testsuite/g++.dg/template/permissive-error1a.C:7:5: note: first error appeared here
7 | ++n; // {
| ^
...
PR c++/116064
gcc/c-family/ChangeLog:
* c.opt (Wtemplate-body): New warning.
gcc/cp/ChangeLog:
* cp-tree.h (erroneous_templates_t): Declare.
(erroneous_templates): Declare.
(cp_seen_error): Declare.
(seen_error): #define to cp_seen_error.
* error.cc (get_current_template): Define.
(relaxed_template_errors): Define.
(cp_adjust_diagnostic_info): Define.
(cp_seen_error): Define.
(cxx_initialize_diagnostics): Set
diagnostic_context::m_adjust_diagnostic_info.
* module.cc (finish_module_processing): Don't write the
module if it contains an erroneous template.
* pt.cc (maybe_diagnose_erroneous_template): Define.
(instantiate_class_template): Call it.
(instantiate_decl): Likewise.
gcc/ChangeLog:
* diagnostic.cc (diagnostic_context::initialize): Set
m_adjust_diagnostic_info.
(diagnostic_context::report_diagnostic): Call
m_adjust_diagnostic_info.
* diagnostic.h (diagnostic_context::m_adjust_diagnostic_info):
New data member.
* doc/invoke.texi (-Wno-template-body): Document.
(-fpermissive): Mention -Wtemplate-body.
gcc/testsuite/ChangeLog:
* g++.dg/ext/typedef-init.C: Downgrade error inside template
to warning due to -fpermissive.
* g++.dg/pr84492.C: Likewise.
* g++.old-deja/g++.pt/crash51.C: Remove unneeded dg-options.
* g++.dg/template/permissive-error1.C: New test.
* g++.dg/template/permissive-error1a.C: New test.
* g++.dg/template/permissive-error1b.C: New test.
* g++.dg/template/permissive-error1c.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
Currently we don't stream the contents of 'nowarn_map'; this means that
warning suppressions don't get applied in importers, which is
particularly relevant for templates (as in the linked testcase).
Rather than streaming the whole contents of 'nowarn_map', this patch
instead just streams the exported suppressions for each tree node
individually, to not build up additional locations and suppressions for
tree nodes that do not need to be streamed.
PR c++/115757
gcc/cp/ChangeLog:
* module.cc (trees_out::core_vals): Write warning specs for
DECLs and EXPRs.
(trees_in::core_vals): Read warning specs.
gcc/ChangeLog:
* tree.h (put_warning_spec_at): Declare new function.
(has_warning_spec): Likewise.
(get_warning_spec): Likewise.
(put_warning_spec): Likewise.
* diagnostic-spec.h (nowarn_spec_t::from_bits): New function.
* diagnostic-spec.cc (put_warning_spec_at): New function.
* warning-control.cc (has_warning_spec): New function.
(get_warning_spec): New function.
(put_warning_spec): New function.
gcc/testsuite/ChangeLog:
* g++.dg/modules/warn-spec-1_a.C: New test.
* g++.dg/modules/warn-spec-1_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
While lazy loading, instantiation of pendings can sometimes recursively
perform name lookup and begin further lazy loading. When using the
'-ftime-report' functionality this causes ICEs as we could start an
already-running timer for the importing.
This patch fixes the issue by using the 'timevar_cond*' API instead to
support such recursive calls.
PR c++/115165
gcc/cp/ChangeLog:
* module.cc (lazy_load_binding): Use 'timevar_cond*' APIs.
(lazy_load_pendings): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/modules/timevar-1_a.H: New test.
* g++.dg/modules/timevar-1_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
With modules, a non-function using-declaration is not completely
interchangable with the declaration that it refers to; in particular,
such a using-declaration may be exported without revealing the name of
the entity it refers to.
This patch fixes this by building USING_DECLs for all using-declarations
that bind a non-function from a different scope. These new decls can
than have purviewness and exportingness attached to them without
affecting the decl that they refer to.
We do this for all such usings, not just usings that may be revealed in
a module; this way we can verify the change in representation against
the (more comprehensive) non-modules testsuites, and in a future patch
we can use the locations of these using-decls to enhance relevant
diagnostics.
Another possible approach would be to reuse OVERLOADs for this, as is
already done within add_binding_entity for modules. I didn't do this
because lots of code (as well as the names of the accessors) makes
assumptions that OVERLOADs refer to function overload sets, and so
splitting this up reduced semantic burden and made it easier to avoid
unintentional changes. This did mean that we need to move out the
definitions of ovl_iterator::{purview,exporting}_p, because the
structures for module decls are declared later on in cp-tree.h.
Building USING_DECLs changed a couple of code paths when adjusting
bindings; in particular, pushdecl recognises global using-declarations
as usings now, and so checks fall through to update_binding. To not
regress g++.dg/lookup/linkage2.C the checks for 'extern' declarations no
longer were sufficient (they don't handle 'extern "C"'); but
duplicate_decls performed all the relevant checks anyway.
Otherwise in general we strip using-decls from all lookup_* functions
where necessary. Over time for diagnostics purposes it would probably
be good to slowly revert this (especially e.g. lookup_elaborated_type
causes some diagnostic quality regressions here) but this patch doesn't
do so to minimise churn.
This patch also tries not to build USING_DECLs when just redeclaring an
existing declaration, and instead reveals that declaration in-place.
This requires reworking some logic handling CONST_DECLs in module
streaming, since a non-using CONST_DECL may now be exported indepenently
of its containing enum.
'add_binding_entity' needs to explicitly write the names of unscoped
enumerators so that lazy loading will trigger when the name is found by
name lookup; it does this by pretending that the enum declarations are
always usings so that it doesn't double-write definitions. By also
checking if the enumerator was marked purview/exported we can use that
to override a non-purview/non-exported TYPE_DECL and ensure it's made
visible regardless.
When reading we should get the exported flag on the enumeration
constant, and so should properly create a binding for it. We don't need
to do anything to handle importedness as that checking is skipped for
EK_USINGs.
Some other places assume that module information for a CONST_DECL
inherits module information from its containing type. This includes:
- get_originating_module_decl, for determining if the name was imported
or has module attachment; I don't /think/ this change should affect
that, so I'm leaving this untouched.
- binding_cmp, for sorting by exportedness; since now an enumerator
could be exported without the containing decl being exported, we need
to handle this here too.
PR c++/114683
gcc/cp/ChangeLog:
* cp-tree.h (class ovl_iterator): Move definitions of purview_p
and exporting_p to name-lookup.cc.
* module.cc (depset::hash::add_binding_entity): Strip
using-decls. Remove workarounds. Handle CONST_DECLs with
different purview/exported from their enum.
(enum ct_bind_flags): Remove unnecessary cbf_wrapped flag.
(module_state::write_cluster): Likewise.
(module_state::read_cluster): Build USING_DECL for non-function
usings.
(binding_cmp): Handle CONST_DECLs with different purview and/or
exported from their enum.
(set_instantiating_module): Support CONST_DECLs.
* name-lookup.cc (get_fixed_binding_slot): Strip USING_DECLs.
(name_lookup::process_binding): Strip USING_DECLs.
(name_lookup::process_module_binding): Remove workaround.
(update_binding): Strip USING_DECLs, remove incorrect check for
non-extern variables.
(ovl_iterator::purview_p): Support USING_DECLs.
(ovl_iterator::exporting_p): Support USING_DECLs.
(walk_module_binding): Handle stat hack type.
(do_nonmember_using_decl): Strip USING_DECLs when comparing;
build USING_DECLs for non-function usings in different scope
rather than binding directly.
(get_namespace_binding): Strip USING_DECLs.
(lookup_name): Strip USING_DECLs.
(lookup_elaborated_type): Strip USING_DECLs.
* decl.cc (poplevel): Still support -Wunused for using-decls.
(lookup_and_check_tag): Remove unnecessary strip_using_decl.
* parser.cc (cp_parser_template_name): Likewise.
(cp_parser_nonclass_name): Likewise.
(cp_parser_class_name): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/lookup/using29.C: Update errors.
* g++.dg/lookup/using53.C: Update errors, add XFAILs.
* g++.dg/modules/using-22_b.C: Remove xfails.
* g++.dg/warn/Wunused-var-18.C: Update error, add check.
* g++.dg/lookup/using68.C: New test.
* g++.dg/modules/using-24_a.C: New test.
* g++.dg/modules/using-24_b.C: New test.
* g++.dg/modules/using-25_a.C: New test.
* g++.dg/modules/using-25_b.C: New test.
* g++.dg/modules/using-enum-4_a.C: New test.
* g++.dg/modules/using-enum-4_b.C: New test.
* g++.dg/modules/using-enum-4_c.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
I noticed there already exists a getter to get the scope of a lambda
from its type directly rather than needing to go via
CLASSTYPE_LAMBDA_EXPR, we may as well use it.
gcc/cp/ChangeLog:
* module.cc (trees_out::get_merge_kind): Use
LAMBDA_TYPE_EXTRA_SCOPE instead of LAMBDA_EXPR_EXTRA_SCOPE.
(trees_out::key_mergeable): Likewise.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
[PR115745]
This C++26 paper allows structured bindings declaration in
if/while/for/switch conditions, where the structured binding shouldn't
be initialized by array (so in the standard only non-union class types;
as extension _Complex will also work and vectors will be diagnosed because
of conversion issues) and the decision variable is the artificial variable
(e in the standard) itself contextually converted to bool or converted to
some integer/enumeration type.
The standard requires that the conversion is evaluated before the get calls
in case of std::tuple* using class, so the largest part of the patch is making
sure this can be done during instantiation without duplicating too much
code.
In cp_parser_condition, creating a TARGET_EXPR to hold temporarily the
bool or int/enum result of the conversion across the get calls is easy, it
could be just added in between cp_finish_decl and cp_finish_decomp, but for
pt.cc there was no easy spot to add that.
In the end, the patch uses DECL_DECOMP_BASE for this. That tree is used
primarily for the user vars or var proxies to point back at the
DECL_ARTIFICIAL e variable, before this patch it has been NULL_TREE on
the base. In some places code was checking if DECL_DECOMP_BASE is NULL_TREE
to find out if it is the base or user var/var proxy.
The patch introduces DECL_DECOMP_IS_BASE macro for what used to be
!DECL_DECOMP_BASE and can stick something else in the base's
DECL_DECOMP_BASE as long as it is not a VAR_DECL.
The patch uses integer_zero_node to mark if/while/for condition structured
binding, integer_one_node to mark switch condition structured binding and
finally cp_finish_decomp sets it to TARGET_EXPR if some get method calls are
emitted and from there the callers can pick that up. This way I also
avoided code duplication between !processing_template_decl parsing and
pt.cc.
2024-07-02 Jakub Jelinek <jakub@redhat.com>
PR c++/115745
gcc/cp/
* cp-tree.h: Implement C++26 P0963R3 - Structured binding declaration
as a condition.
(DECL_DECOMP_BASE): Adjust comment.
(DECL_DECOMP_IS_BASE): Define.
* parser.cc (cp_parser_selection_statement): Adjust
cp_parser_condition caller.
(cp_parser_condition): Add KEYWORD argument. Parse
C++26 structured bindings in conditions.
(cp_parser_c_for, cp_parser_iteration_statement): Adjust
cp_parser_condition callers.
(cp_parser_simple_declaration): Adjust
cp_parser_decomposition_declaration caller.
(cp_parser_decomposition_declaration): Add KEYWORD argument.
If it is not RID_MAX, diagnose for C++23 and older rather than C++14
and older. Set DECL_DECOMP_BASE to integer_zero_node for structured
bindings used in if/while/for conditions or integer_one_node for
those used in switch conditions.
* decl.cc (poplevel, check_array_initializer): Use DECL_DECOMP_IS_BASE
instead of !DECL_DECOMP_BASE.
(cp_finish_decomp): Diagnose array initializer for structured bindings
used in conditions. If using std::tuple_{size,element}, emit
conversion to bool or integer/enumeration of e into a TARGET_EXPR
before emitting get method calls.
* decl2.cc (mark_used): Use DECL_DECOMP_IS_BASE instead of
!DECL_DECOMP_BASE.
* module.cc (trees_in::tree_node): Likewise.
* typeck.cc (maybe_warn_about_returning_address_of_local): Likewise.
* semantics.cc (maybe_convert_cond): For structured bindings with
TARGET_EXPR DECL_DECOMP_BASE use that as condition.
(finish_switch_cond): Likewise.
gcc/testsuite/
* g++.dg/cpp1z/decomp16.C: Adjust expected diagnostics.
* g++.dg/cpp26/decomp3.C: New test.
* g++.dg/cpp26/decomp4.C: New test.
* g++.dg/cpp26/decomp5.C: New test.
* g++.dg/cpp26/decomp6.C: New test.
* g++.dg/cpp26/decomp7.C: New test.
* g++.dg/cpp26/decomp8.C: New test.
* g++.dg/cpp26/decomp9.C: New test.
* g++.dg/cpp26/decomp10.C: New test.
|
|
Adjusting the comment I added in r15-1223 to clarify that this is a
workaround for a bug elsewhere.
gcc/cp/ChangeLog:
* module.cc (depset::hash::add_binding_entity): Adjust comment.
|
|
exception_ptr.h contains
namespace __exception_ptr
{
class exception_ptr;
}
using __exception_ptr::exception_ptr;
so when module std tries to 'export using std::exception_ptr', it names
another using-directive rather than the class directly, so __exception_ptr
is never explicitly opened in module purview.
gcc/cp/ChangeLog:
* module.cc (depset::hash::add_binding_entity): Set
DECL_MODULE_PURVIEW_P instead of asserting.
gcc/testsuite/ChangeLog:
* g++.dg/modules/using-20_a.C: New test.
|
|
Within a source file, #include is translated to import if a suitable header
unit is available, but this wasn't working with -include. This turned out
to be because we suppressed the translation before the beginning of the
main file. After removing that, I had to tweak libcpp file handling to
accommodate the way it moves from an -include to the main file.
gcc/ChangeLog:
* doc/invoke.texi (C++ Modules): Mention -include.
gcc/cp/ChangeLog:
* module.cc (maybe_translate_include): Allow before the main file.
libcpp/ChangeLog:
* files.cc (_cpp_stack_file): LC_ENTER for -include header unit.
gcc/testsuite/ChangeLog:
* g++.dg/modules/dashinclude-1_b.C: New test.
* g++.dg/modules/dashinclude-1_a.H: New test.
|
|
This patch fixes a couple issues with the current handling of revealing
declarations with using-decls.
Firstly, doing 'remove_node' when handling function overload sets is not
safe, because it not only mutates the OVERLOAD we're walking over but
potentially any other references to this OVERLOAD that are cached from
phase-1 template lookup. This causes the attached using-17 testcase to
fail because the overload set in 'X::test()' no longer contains the
'ns::f(T)' template once instantiated at the end of the file.
This patch works around this by simply not removing the old declaration.
This does make the overload list potentially longer than it otherwise
would have been, but only when re-exporting the same set of functions in
a using-decl. Additionally, because 'ovl_insert' always prepends these
newly inserted overloads, repeated exported using-decls won't continue
to add declarations, as the first exported using-decl will be found
before the original (unexported) declaration.
Another, related, issue is that using-decls of GMF entities currently
doesn't mark them as reachable unless they are also exported, and thus
they may not be available in e.g. module implementation units. We solve
this with a new flag on OVERLOADs set when they are declared within the
module purview. This starts to run into the more general issue of
handling using-decls of non-functions (see e.g. PR114863) but by just
marking such GMF entities as purview we can work around this for now.
This also allows us to get rid of the special-casing of exported
using-decls in 'add_binding_entity', which was incorrect anyway: a
non-exported using-decl still needs to be emitted anyway if it lives in
the module purview, even if referring to a non-purview item.
PR c++/114867
gcc/cp/ChangeLog:
* cp-tree.h (OVL_PURVIEW_P): New.
(ovl_iterator::purview_p): New.
* module.cc (depset::hash::add_binding_entity): Only ignore
entities not within module purview. Set OVL_PURVIEW_P on new
OVERLOADs for emitted declarations.
(module_state::read_cluster): Imported using-decls are always
in purview, mark as OVL_PURVIEW_P.
* name-lookup.h (enum WMB_Flags): New WMB_Purview flag.
* name-lookup.cc (walk_module_binding): Set WMB_Purview as
needed.
(do_nonmember_using_decl): Don't remove from existing OVERLOADs.
Also reveal non-exported decls. Also reveal 'extern "C"' decls.
Add workaround to reveal non-function decls.
* tree.cc (ovl_insert): Adjust to also set OVL_PURVIEW_P when
needed.
gcc/testsuite/ChangeLog:
* g++.dg/modules/using-17_a.C: New test.
* g++.dg/modules/using-17_b.C: New test.
* g++.dg/modules/using-18_a.C: New test.
* g++.dg/modules/using-18_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
If a user mistakenly includes a standard library header within the
module purview, they currently get a confusing "declaration conflicts
with builtin" error. This patch updates the message to include "in
module", to help guide the user towards the likely cause.
PR c++/102345
gcc/cp/ChangeLog:
* module.cc (module_may_redeclare): Update error message.
gcc/testsuite/ChangeLog:
* g++.dg/modules/enum-12.C: Test for updated error.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
This appears to be an oversight in the definition of module_has_cmi_p.
This change will allow us to use the function directly in more places
that need to additional work only if generating a module CMI in the
future, allowing us to do additional work only when we know we need it.
gcc/cp/ChangeLog:
* cp-tree.h (module_has_cmi_p): Also include header units.
(module_maybe_has_cmi_p): Update comment.
* module.cc (set_defining_module): Only need to track
declarations for later exporting if the module may have a CMI.
(set_defining_module_for_partial_spec): Likewise.
* name-lookup.cc (pushdecl): Likewise.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
Constrained partial specialisations aren't all necessarily tracked on
the instantiation table. The modules code uses a separate
'partial_specializations' table to track them instead to ensure that
they get walked and emitted when emitting a module, but currently this
does not always happen.
The attached testcase fails in two ways. First, because the partial
specialisation is just a declaration (and not a definition),
'set_defining_module' never ends up getting called on it and so it never
gets added to the partial specialisation table. We fix this by ensuring
that when partial specializations are created they always get added, and
so we never miss one. To prevent adding partial specialisations multiple
times we split this out as a new function.
The second way it fails is that when exporting the primary interface for
a module with partitions, we also re-walk the specializations of all
imported partitions to merge them into a single BMI. So this patch
ensures that after calling 'match_mergeable_specialization' we also
ensure that if the name came from a partition it gets added to the
specialization table so that a dependency is correctly created for it.
PR c++/114947
gcc/cp/ChangeLog:
* cp-tree.h (set_defining_module_for_partial_spec): Declare.
* module.cc (trees_in::decl_value): Track partial specs coming
from partitions.
(set_defining_module): Don't track partial specialisations here
anymore.
(set_defining_module_for_partial_spec): New function.
* pt.cc (process_partial_specialization): Call it.
gcc/testsuite/ChangeLog:
* g++.dg/modules/partial-4_a.C: New test.
* g++.dg/modules/partial-4_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
I got notified by Linaro CI and by checking testresults that there seems
to be some occasional failures in tpl-friend-4_b.C on some architectures
and standards modes since r15-59-gb5f6a56940e708. I haven't been able
to reproduce but looking at the backtrace I suspect the issue is that
we're adding to the 'imported_temploid_friend' map a decl that is
ultimately discarded, which then has its address reused by a later decl
causing a failure in the assert in 'set_originating_module'.
This patch fixes the problem by ensuring 'imported_temploid_friends' is
correctly marked as a GTY root, and that 'duplicate_decls' properly
removes entries from the map for declarations that it frees.
PR c++/114275
gcc/cp/ChangeLog:
* cp-tree.h (remove_defining_module): Declare.
* decl.cc (duplicate_decls): Call remove_defining_module on
to-be-freed newdecl.
* module.cc (imported_temploid_friends): Mark as GTY root...
(init_modules): ...and allocate from ggc.
(trees_in::decl_value): Only track for declarations that won't
be discarded.
(remove_defining_module): New function.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
The change in r14-8408 to also emit partial specializations in the
global module fragment caused the regression in the linked PR; this
patch fixes this by restricting emitted GM partial specializations to
those that are actually used.
PR c++/114630
gcc/cp/ChangeLog:
* module.cc (depset::hash::add_partial_entities): Mark GM
specializations as unreached.
(depset::hash::find_dependencies): Also reach entities in the
DECL_TEMPLATE_SPECIALIZATIONS list.
gcc/testsuite/ChangeLog:
* g++.dg/modules/partial-3.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
This patch implements the changes described in
https://github.com/itanium-cxx-abi/cxx-abi/pull/171.
One restriction that is lifted in the ABI that hasn't been updated here
is that the ABI no longer requires unique vtables to be emitted with
vague linkage. I haven't changed this behaviour for this patch, but in
the future we could look into changing the relevant target hook
('class_data_always_comdat') to default to 'false'. But the current
behaviour is more forgiving to changes in key function identification.
Since the ABI for vtables attached to named modules no longer depends on
key methods, this also resolves the issue described in PR c++/105224.
PR c++/105224
gcc/cp/ChangeLog:
* class.cc (finish_struct_1): Also push classes attached to a
module into the 'keyed_classes' list.
* decl.cc (record_key_method_defined): Don't push classes
attached to a named module into the 'keyed_classes' list.
* module.cc (trees_in::read_class_def): Likewise.
* decl2.cc (import_export_class): Uniquely emit vtables for
non-template classes attached to a named module.
(vtables_uniquely_emitted): New function.
(import_export_decl): Update comments. Update with knowledge
about new kinds of uniquely emitted vtables.
gcc/testsuite/ChangeLog:
* g++.dg/modules/virt-2_a.C: Update linkage requirements.
* g++.dg/modules/virt-2_b.C: Likewise.
* g++.dg/modules/virt-2_c.C: Likewise.
* g++.dg/modules/virt-4_a.C: New test.
* g++.dg/modules/virt-4_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
The modules code currently neglects to set OVL_USING_P on the dependency
created for a using-decl, which causes it not to remember that the
OVL_EXPORT_P flag had been set on it when emitted from the primary
interface unit. This patch ensures that it occurs.
PR c++/114868
gcc/cp/ChangeLog:
* module.cc (depset::hash::add_binding_entity): Propagate
OVL_USING_P for using-declarations.
gcc/testsuite/ChangeLog:
* g++.dg/modules/using-15_a.C: New test.
* g++.dg/modules/using-15_b.C: New test.
* g++.dg/modules/using-15_c.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
This patch fixes a number of issues with the handling of temploid friend
declarations.
The primary issue is that instantiations of friend declarations should
attach the declaration to the same module as the befriending class, by
[module.unit] p7.1 and [temp.friend] p2; this could be a different
module from the current TU, and so needs special handling.
The other main issue here is that we can't assume that just because name
lookup didn't find a definition for a hidden class template, that it
doesn't exist at all: it could be a non-exported entity that we've
nevertheless streamed in from an imported module. We need to ensure
that when instantiating template friend classes that we return the same
TEMPLATE_DECL that we got from our imports, otherwise we will get later
issues with 'duplicate_decls' (rightfully) complaining that they're
different when trying to merge.
This doesn't appear necessary for function templates due to the existing
name lookup handling already finding these hidden declarations.
PR c++/105320
PR c++/114275
gcc/cp/ChangeLog:
* cp-tree.h (propagate_defining_module): Declare.
(lookup_imported_hidden_friend): Declare.
* decl.cc (duplicate_decls): Also check if hidden decls can be
redeclared in this module.
* module.cc (imported_temploid_friends): New.
(init_modules): Initialize it.
(trees_out::decl_value): Write it; don't consider imported
temploid friends as attached to a module.
(trees_in::decl_value): Read it.
(get_originating_module_decl): Follow the owning decl for an
imported temploid friend.
(propagate_defining_module): New.
* name-lookup.cc (get_mergeable_namespace_binding): New.
(lookup_imported_hidden_friend): New.
* pt.cc (tsubst_friend_function): Propagate defining module for
new friend functions.
(tsubst_friend_class): Lookup imported hidden friends. Check
for valid module attachment of existing names. Propagate
defining module for new classes.
gcc/testsuite/ChangeLog:
* g++.dg/modules/tpl-friend-10_a.C: New test.
* g++.dg/modules/tpl-friend-10_b.C: New test.
* g++.dg/modules/tpl-friend-10_c.C: New test.
* g++.dg/modules/tpl-friend-10_d.C: New test.
* g++.dg/modules/tpl-friend-11_a.C: New test.
* g++.dg/modules/tpl-friend-11_b.C: New test.
* g++.dg/modules/tpl-friend-12_a.C: New test.
* g++.dg/modules/tpl-friend-12_b.C: New test.
* g++.dg/modules/tpl-friend-12_c.C: New test.
* g++.dg/modules/tpl-friend-12_d.C: New test.
* g++.dg/modules/tpl-friend-12_e.C: New test.
* g++.dg/modules/tpl-friend-12_f.C: New test.
* g++.dg/modules/tpl-friend-13_a.C: New test.
* g++.dg/modules/tpl-friend-13_b.C: New test.
* g++.dg/modules/tpl-friend-13_c.C: New test.
* g++.dg/modules/tpl-friend-13_d.C: New test.
* g++.dg/modules/tpl-friend-13_e.C: New test.
* g++.dg/modules/tpl-friend-13_f.C: New test.
* g++.dg/modules/tpl-friend-13_g.C: New test.
* g++.dg/modules/tpl-friend-14_a.C: New test.
* g++.dg/modules/tpl-friend-14_b.C: New test.
* g++.dg/modules/tpl-friend-14_c.C: New test.
* g++.dg/modules/tpl-friend-14_d.C: New test.
* g++.dg/modules/tpl-friend-9.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
Currently different places calling 'module_may_redeclare' all emit very
similar but slightly different error messages, and handle different
kinds of declarations differently. This patch makes the function
perform its own error messages so that they're all in one place, and
prepares it for use with temploid friends.
gcc/cp/ChangeLog:
* cp-tree.h (module_may_redeclare): Add default parameter.
* decl.cc (duplicate_decls): Don't emit errors for failed
module_may_redeclare.
(xref_tag): Likewise.
(start_enum): Likewise.
* semantics.cc (begin_class_definition): Likewise.
* module.cc (module_may_redeclare): Clean up logic. Emit error
messages on failure.
gcc/testsuite/ChangeLog:
* g++.dg/modules/enum-12.C: Update error message.
* g++.dg/modules/friend-5_b.C: Likewise.
* g++.dg/modules/shadow-1_b.C: Likewise.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
When adding to CLASSTYPE_BEFRIENDING_CLASSES as part of installing an
imported class definition, we need to look through TEMPLATE_DECL like
make_friend_class does.
Otherwise in the below testcase we won't add _Hashtable<int, int> to
CLASSTYPE_BEFRIENDING_CLASSES of _Map_base, which leads to a bogus
access check failure for _M_hash_code.
PR c++/114889
gcc/cp/ChangeLog:
* module.cc (trees_in::read_class_def): Look through
TEMPLATE_DECL when adding to CLASSTYPE_BEFRIENDING_CLASSES.
gcc/testsuite/ChangeLog:
* g++.dg/modules/friend-8_a.H: New test.
* g++.dg/modules/friend-8_b.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
When merging an imported function template specialization with an
existing one, if the existing one has an undeduced return type and the
imported one's is already deduced, we need to propagate the deduced type
since once we install the imported definition we won't get a chance to
deduce it by normal means.
So this patch makes is_matching_decl propagate the deduced return
type alongside our propagation of the exception specification.
Another option would be to propagate it later when installing the
imported definition from read_function_def, but it seems preferable
to do it sooner rather than later.
PR c++/114795
gcc/cp/ChangeLog:
* module.cc (trees_in::is_matching_decl): Propagate deduced
function return type.
gcc/testsuite/ChangeLog:
* g++.dg/modules/auto-4_a.H: New test.
* g++.dg/modules/auto-4_b.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
A typo in r14-6978 made us emit too many things. This ensures that we
don't emit using-declarations from the GMF that we don't need to.
PR c++/114600
gcc/cp/ChangeLog:
* module.cc (depset::hash::add_binding_entity): Require both
WMB_Using and WMB_Export for GMF entities.
gcc/testsuite/ChangeLog:
* g++.dg/modules/using-14.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Co-authored-by: Patrick Palka <ppalka@redhat.com>
|
|
I wonder if more generally we need to be doing more work when importing
definitions from header units especially to handle all the work that
'make_rtl_for_nonlocal_decl' and 'rest_of_decl_compilation' would have
been performing. But this patch fixes at least one missing step.
PR c++/106820
gcc/cp/ChangeLog:
* module.cc (trees_in::decl_value): Assemble alias when needed.
gcc/testsuite/ChangeLog:
* g++.dg/modules/pr106820_a.H: New test.
* g++.dg/modules/pr106820_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
gcc/cp/ChangeLog:
* module.cc (struct bytes_in::bits_in): Define defaulted
move ctor.
(struct bytes_out::bits_out): Likewise.
|
|
One would expect consecutive calls to bytes_in/out::b for streaming
adjacent bits, as is done for tree flag streaming, to at least be
optimized by the compiler into individual bit operations using
statically known bit positions (and ideally combined into larger sized
reads/writes).
Unfortunately this doesn't happen because the compiler has trouble
tracking the values of this->bit_pos and this->bit_val across the
calls, likely because the compiler doesn't know the value of 'this'.
Thus for each consecutive bit stream operation, bit_pos and bit_val are
loaded from 'this', checked if buffering is needed, and finally the bit
is extracted from bit_val according to the (unknown) bit_pos, even
though relative to the previous operation (if we didn't need to buffer)
bit_val is unchanged and bit_pos is just 1 larger. This ends up being
quite slow, with tree_node_bools taking 10% of time when streaming in
the std module.
This patch improves this by making tracking of bit_pos and bit_val
easier for the compiler. Rather than bit_pos and bit_val being members
of the (effectively global) bytes_in/out objects, this patch factors out
the bit streaming code/state into separate classes bits_in/out that get
constructed locally as needed for bit streaming. Since these objects
are now clearly local, the compiler can more easily track their values
and optimize away redundant buffering checks.
And since bit streaming is intended to be batched it's natural for these
new classes to be RAII-enabled such that the bit stream is flushed upon
destruction.
In order to make the most of this improved tracking of bit position,
this patch changes parts where we conditionally stream a tree flag
to unconditionally stream (the flag or a dummy value). That way
the number of bits streamed and the respective bit positions are as
statically known as reasonably possible. In lang_decl_bools and
lang_type_bools this patch makes us flush the current bit buffer at the
start so that subsequent bit positions are in turn statically known.
And in core_bools, we can add explicit early exits utilizing invariants
that the compiler can't figure out itself (e.g. a tree code can't have
both TS_TYPE_COMMON and TS_DECL_COMMON, and if a tree code doesn't have
TS_DECL_COMMON then it doesn't have TS_DECL_WITH_VIS).
This patch also moves the definitions of the relevant streaming classes
into anonymous namespaces so that the compiler can make more informed
decisions about inlining their member functions.
After this patch, compile time for a simple Hello World using the std
module is reduced by 7% with a release compiler. The on-disk size of
the std module increases by 0.4% (presumably due to the extra flushing
done in lang_decl_bools and lang_type_bools).
The bit stream out performance isn't improved as much as the stream in
due to the spans/lengths instrumentation performed on stream out (which
maybe should be disabled for release builds?)
gcc/cp/ChangeLog:
* module.cc: Update comment about classes defined within.
(class data): Enclose in an anonymous namespace.
(data::calc_crc): Moved from bytes::calc_crc.
(class bytes): Remove. Move bit_flush to namespace scope.
(class bytes_in): Enclose in an anonymous namespace. Inherit
directly from data and adjust accordingly. Move b and bflush
members to bits_in.
(class bytes_out): As above. Remove is_set static data member.
(bit_flush): Moved from class bytes.
(struct bytes_in::bits_in): Define.
(struct bytes_out::bits_out): Define.
(bytes_in::stream_bits): Define.
(bytes_out::stream_bits): Define.
(bytes_out::bflush): Moved to bits_out/in.
(bytes_in::bflush): Likewise
(bytes_in::bfill): Removed.
(bytes_out::b): Moved to bits_out/in.
(bytes_in::b): Likewise.
(class trees_in): Enclose in an anonymous namespace.
(class trees_out): Enclose in an anonymous namespace.
(trees_out::core_bools): Add bits_out/in parameter and use it.
Unconditionally stream a bit for public_flag. Add early exits
as appropriate.
(trees_out::core_bools): Likewise.
(trees_out::lang_decl_bools): Add bits_out/in parameter and use
it. Flush the current bit buffer at the start. Unconditionally
stream a bit for module_keyed_decls_p.
(trees_in::lang_decl_bools): Likewise.
(trees_out::lang_type_bools): Add bits_out/in parameter and use
it. Flush the current bit buffer at the start.
(trees_in::lang_type_bools): Likewise.
(trees_out::tree_node_bools): Construct a bits_out object and
use/pass it.
(trees_in::tree_node_bools): Likewise.
(trees_out::decl_value): Likewise.
(trees_in::decl_value): Likewise.
(module_state::write_define): Likewise.
(module_state::read_define): Likewise.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
One known missing piece in the modules implementation is merging of a
streamed-in local type (class or enum) with the corresponding in-TU
version of the local type. This missing piece turns out to cause a
hard-to-reduce use-after-free GC issue due to the entity_ary not being
marked as a GC root (deliberately), and manifests as a serialization
error on stream-in as in PR99426 (see comment #6 for a reduction). It's
also reproducible on trunk when running the xtreme-header tests without
-fno-module-lazy.
This patch implements this missing piece, making us merge such local
types according to their position within the containing function's
definition, analogous to how we merge FIELD_DECLs of a class according
to their index in the TYPE_FIELDS list.
PR c++/99426
gcc/cp/ChangeLog:
* module.cc (merge_kind::MK_local_type): New enumerator.
(merge_kind_name): Update.
(trees_out::chained_decls): Move BLOCK-specific handling
of DECL_LOCAL_DECL_P decls to ...
(trees_out::core_vals) <case BLOCK>: ... here. Stream
BLOCK_VARS manually.
(trees_in::core_vals) <case BLOCK>: Stream BLOCK_VARS
manually. Handle deduplicated local types..
(trees_out::key_local_type): Define.
(trees_in::key_local_type): Define.
(trees_out::get_merge_kind) <case FUNCTION_DECL>: Return
MK_local_type for a local type.
(trees_out::key_mergeable) <case FUNCTION_DECL>: Use
key_local_type.
(trees_in::key_mergeable) <case FUNCTION_DECL>: Likewise.
(trees_in::is_matching_decl): Be flexible with type mismatches
for local entities.
(trees_in::register_duplicate): Also register the
DECL_TEMPLATE_RESULT of a TEMPLATE_DECL as a duplicate.
(depset_cmp): Return 0 for equal IDENTIFIER_HASH_VALUEs.
gcc/testsuite/ChangeLog:
* g++.dg/modules/merge-17.h: New test.
* g++.dg/modules/merge-17_a.H: New test.
* g++.dg/modules/merge-17_b.C: New test.
* g++.dg/modules/xtreme-header-7_a.H: New test.
* g++.dg/modules/xtreme-header-7_b.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
The below testcases use a lambda-expr as a template argument and they
all trip over the below added tsubst_lambda_expr sanity check ultimately
because current_template_parms is empty which causes push_template_decl
to return error_mark_node from the call to begin_lambda_type. Were it
not for the sanity check this silent error_mark_node result leads to
nonsensical errors down the line, or silent breakage.
In the first testcase, we hit this assert during instantiation of the
dependent alias template-id c1_t<_Data> from instantiate_template, which
clears current_template_parms via push_to_top_level. Similar story for
the second testcase. For the third testcase we hit the assert during
partial instantiation of the member template from instantiate_class_template
which similarly calls push_to_top_level.
These testcases illustrate that templated substitution into a lambda-expr
is not always possible, in particular when we lost the relevant template
context. I experimented with recovering the template context by making
tsubst_lambda_expr fall back to using scope_chain->prev->template_parms if
current_template_parms is empty which worked but seemed like a hack. I
also experimented with preserving the template context by keeping
current_template_parms set during instantiate_template for a dependent
specialization which also worked but it's at odds with the fact that we
cache dependent specializations (and so they should be independent of
the template context).
So instead of trying to make such substitution work, this patch uses the
extra-args mechanism to defer templated substitution into a lambda-expr
when we lost the relevant template context.
PR c++/114393
PR c++/107457
PR c++/93595
gcc/cp/ChangeLog:
* cp-tree.h (LAMBDA_EXPR_EXTRA_ARGS): Define.
(tree_lambda_expr::extra_args): New field.
* module.cc (trees_out::core_vals) <case LAMBDA_EXPR>: Stream
LAMBDA_EXPR_EXTRA_ARGS.
(trees_in::core_vals) <case LAMBDA_EXPR>: Likewise.
* pt.cc (has_extra_args_mechanism_p): Return true for LAMBDA_EXPR.
(tree_extra_args): Handle LAMBDA_EXPR.
(tsubst_lambda_expr): Use LAMBDA_EXPR_EXTRA_ARGS to defer templated
substitution into a lambda-expr if we lost the template context.
Add sanity check for error_mark_node result from begin_lambda_type.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/lambda-targ2.C: New test.
* g++.dg/cpp2a/lambda-targ3.C: New test.
* g++.dg/cpp2a/lambda-targ4.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
The testcase in comment 15 of the linked PR is caused because the
following assumption in depset::hash::make_dependency doesn't hold:
if (DECL_LANG_SPECIFIC (not_tmpl)
&& DECL_MODULE_IMPORT_P (not_tmpl))
{
/* Store the module number and index in cluster/section,
so we don't have to look them up again. */
unsigned index = import_entity_index (decl);
module_state *from = import_entity_module (index);
/* Remap will be zero for imports from partitions, which
we want to treat as-if declared in this TU. */
if (from->remap)
{
dep->cluster = index - from->entity_lwm;
dep->section = from->remap;
dep->set_flag_bit<DB_IMPORTED_BIT> ();
}
}
This is because at least for template specialisations, we first see the
declaration in the header unit imported from the partition, and then the
instantiation provided by the partition itself. This means that the
'import_entity_index' lookup doesn't report that the specialisation was
declared in the partition and thus should be considered as-if it was
part of the TU, and get emitted into the CMI.
We always need to emit definitions from module partitions into the
primary module interface's CMI, as unlike with other kinds of transitive
imports the built CMIs for module partitions are not visible to
importers.
To fix this, this patch allows, as a special case for installing an
entity from a partition, to overwrite the entity_map entry with the
(later) index into the partition so that this assumption holds again.
We only do this for the first time we override with a partition, so that
entities are at least still reported as originating from the first
imported partition that declares them (rather than the last); existing
tests check for this and this seems to be a friendlier approach to go
for, albeit slightly more expensive.
PR c++/99377
gcc/cp/ChangeLog:
* module.cc (trees_in::install_entity): Overwrite entity map
index if installing from a partition.
gcc/testsuite/ChangeLog:
* g++.dg/modules/pr99377-3_a.H: New test.
* g++.dg/modules/pr99377-3_b.C: New test.
* g++.dg/modules/pr99377-3_c.C: New test.
* g++.dg/modules/pr99377-3_d.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
Some targets make use of POLY_INT_CSTs and other custom builtin types,
which currently violate some assumptions when streaming. This patch adds
support for them, such as types like Aarch64 __fp16, PowerPC __ibm128,
and vector types thereof.
This patch doesn't provide "full" support of AArch64 SVE, however, since
for that we would need to support 'target' nodes (tracked in PR108080).
Adding the new builtin types means that on Aarch64 we now have 217
global trees created on initialisation (up from 191), so this patch also
slightly bumps the initial size of the fixed_trees allocation to 250.
PR c++/98645
PR c++/98688
PR c++/111224
gcc/cp/ChangeLog:
* module.cc (enum tree_tag): Add new tag for builtin types.
(trees_out::start): POLY_INT_CSTs can be emitted.
(trees_in::start): Likewise.
(trees_out::core_vals): Stream POLY_INT_CSTs.
(trees_in::core_vals): Likewise.
(trees_out::type_node): Handle vectors with multiple coeffs.
(trees_in::tree_node): Likewise.
(init_modules): Register target-specific builtin types. Bump
initial capacity slightly.
gcc/testsuite/ChangeLog:
* g++.dg/modules/target-aarch64-1_a.C: New test.
* g++.dg/modules/target-aarch64-1_b.C: New test.
* g++.dg/modules/target-powerpc-1_a.C: New test.
* g++.dg/modules/target-powerpc-1_b.C: New test.
* g++.dg/modules/target-powerpc-2_a.C: New test.
* g++.dg/modules/target-powerpc-2_b.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
|
|
We currently always stream DECL_INTERFACE_KNOWN, which is needed since
many kinds of declarations already have their interface determined at
parse time. But for vtables and type-info declarations we need to
re-evaluate on stream-in as whether they need to be emitted or not
changes in each TU, so this patch clears DECL_INTERFACE_KNOWN on these
kinds of declarations so that they can go through 'import_export_decl'
again.
Note that the precise details of the virt-2 tests will need to change
when we implement the resolution of [1], for now I just updated the test
to not fail with the new (current) semantics.
[1]: https://github.com/itanium-cxx-abi/cxx-abi/pull/171
PR c++/114229
gcc/cp/ChangeLog:
* module.cc (trees_out::core_bools): Redetermine
DECL_INTERFACE_KNOWN on stream-in for vtables and tinfo.
* decl2.cc (import_export_decl): Add fixme for ABI changes with
module vtables and tinfo.
gcc/testsuite/ChangeLog:
* g++.dg/modules/virt-2_b.C: Update test to acknowledge that we
now emit vtables here too.
* g++.dg/modules/virt-3_a.C: New test.
* g++.dg/modules/virt-3_b.C: New test.
* g++.dg/modules/virt-3_c.C: New test.
* g++.dg/modules/virt-3_d.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
|
|
Alias templates are weird in that their specializations can appear in
both decl_specializations and type_specializations. They're always in
the decl table, and additionally appear in the type table only at parse
time via finish_template_type. There seems to be no good reason for
them to appear in both tables, and the code paths end up stepping over
each other in particular for a partial instantiation such as
A<B>::key_arg<T> in the below modules testcase: the type code path
(lookup_template_class) wants to set TI_TEMPLATE to the most general
template whereas the decl code path (tsubst_template_decl called during
instantiation of A<B>) already set TI_TEMPLATE to the partially
instantiated TEMPLATE_DECL. This TI_TEMPLATE change ends up confusing
modules which decides to stream the logically equivalent TYPE_DECL and
TEMPLATE_DECL for this partial instantiation separately.
This patch fixes this by making lookup_template_class dispatch to
instantiate_alias_template early for alias template specializations.
In turn we now add such specializations only to the decl table. This
admits some nice simplification in the modules code which otherwise has
to cope with such specializations appearing in both tables.
PR c++/103994
gcc/cp/ChangeLog:
* cp-tree.h (add_mergeable_specialization): Remove second
parameter.
* module.cc (depset::disc_bits::DB_ALIAS_TMPL_INST_BIT): Remove.
(depset::disc_bits::DB_ALIAS_SPEC_BIT): Remove.
(depset::is_alias_tmpl_inst): Remove.
(depset::is_alias): Remove.
(merge_kind::MK_tmpl_alias_mask): Remove.
(merge_kind::MK_alias_spec): Remove.
(merge_kind_name): Remove entries for alias specializations.
(trees_out::core_vals) <case TEMPLATE_DECL>: Adjust after
removing is_alias_tmpl_inst.
(trees_in::decl_value): Adjust add_mergeable_specialization
calls.
(trees_out::get_merge_kind) <case depset::EK_SPECIALIZATION>:
Use MK_decl_spec for alias template specializations.
(trees_out::key_mergeable): Simplify after MK_tmpl_alias_mask
removal.
(depset::hash::make_dependency): Adjust after removing
DB_ALIAS_TMPL_INST_BIT.
(specialization_add): Don't allow alias templates when !decl_p.
(depset::hash::add_specializations): Remove now-dead code
accomodating alias template specializations in the type table.
* pt.cc (lookup_template_class): Dispatch early to
instantiate_alias_template for alias templates. Simplify
accordingly.
(add_mergeable_specialization): Remove alias_p parameter and
simplify accordingly.
gcc/testsuite/ChangeLog:
* g++.dg/modules/pr99425-1_b.H: s/alias/decl in dump scan.
* g++.dg/modules/tpl-alias-1_a.H: Likewise.
* g++.dg/modules/tpl-alias-2_a.H: New test.
* g++.dg/modules/tpl-alias-2_b.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
The unreduced testcase from PR110730 crashes at runtime ultimately
because we don't stream the abi_tag attribute on inline namespaces and
so the filesystem::current_path() call resolves to the non-C++11 ABI
version even though the C++11 ABI is active, leading to a crash when
destroying the path temporary (which contains an std::string member).
Similar story for the PR105512 testcase.
While we do stream the DECL_ATTRIBUTES of all decls that go through
the generic tree streaming routines, it seems namespaces are streamed
separately from other decls and we don't use the generic routines for
them. So this patch makes us stream the abi_tag manually for (inline)
namespaces.
PR c++/110730
PR c++/105512
gcc/cp/ChangeLog:
* module.cc (module_state::write_namespaces): Stream the
abi_tag attribute of an inline namespace.
(module_state::read_namespaces): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/modules/hello-2_a.C: New test.
* g++.dg/modules/hello-2_b.C: New test.
* g++.dg/modules/namespace-6_a.H: New test.
* g++.dg/modules/namespace-6_b.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
When streaming in a nested template-template parameter as in the
attached testcase, we end up reaching the containing template-template
parameter in 'tpl_parms_fini'. We should not set the DECL_CONTEXT to
this (nested) template-template parameter, as it should already be the
struct that the outer template-template parameter is declared on.
The precise logic for what DECL_CONTEXT should be for a template
template parameter in various situations seems rather obscure. Rather
than trying to determine the assumptions that need to hold, it seems
simpler to just always re-stream the DECL_CONTEXT as needed for now.
PR c++/98881
gcc/cp/ChangeLog:
* module.cc (trees_out::tpl_parms_fini): Stream out DECL_CONTEXT
for template template parameters.
(trees_in::tpl_parms_fini): Read it.
gcc/testsuite/ChangeLog:
* g++.dg/modules/tpl-tpl-parm-3.h: New test.
* g++.dg/modules/tpl-tpl-parm-3_a.H: New test.
* g++.dg/modules/tpl-tpl-parm-3_b.C: New test.
* g++.dg/modules/tpl-tpl-parm-3_c.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
Here the TEMPLATE_DECL representing the template friend declaration
naming B has class scope since the template B has class scope, but
get_merge_kind assumes all DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P
TEMPLATE_DECL have namespace scope and wrongly returns MK_named instead
of MK_local_friend for the friend.
gcc/cp/ChangeLog:
* module.cc (trees_out::get_merge_kind) <case depset::EK_DECL>:
Accomodate class-scope DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P
TEMPLATE_DECL. Consolidate IDENTIFIER_ANON_P cases.
gcc/testsuite/ChangeLog:
* g++.dg/modules/friend-7.h: New test.
* g++.dg/modules/friend-7_a.H: New test.
* g++.dg/modules/friend-7_b.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
|
|
For local enums defined in a non-template function or a function template
instantiation it seems we neglect to make the function depend on the enum
definition (which modules considers logically separate), which ultimately
causes the enum definition to not be properly streamed before uses
within the function definition are streamed.
The code responsible for noting such dependencies is
gcc/cp/module.cc
@@ -8784,17 +8784,6 @@ trees_out::decl_node (tree decl, walk_kind ref)
depset *dep = NULL;
if (streaming_p ())
dep = dep_hash->find_dependency (decl);
! else if (TREE_CODE (ctx) != FUNCTION_DECL
! || TREE_CODE (decl) == TEMPLATE_DECL
! || (dep_hash->sneakoscope && DECL_IMPLICIT_TYPEDEF_P (decl))
! || (DECL_LANG_SPECIFIC (decl)
! && DECL_MODULE_IMPORT_P (decl)))
! {
! auto kind = (TREE_CODE (decl) == NAMESPACE_DECL
! && !DECL_NAMESPACE_ALIAS (decl)
! ? depset::EK_NAMESPACE : depset::EK_DECL);
! dep = dep_hash->add_dependency (decl, kind);
! }
if (!dep)
{
and the condition there notably excludes local TYPE_DECLs from a
non-template-pattern function (when streaming a template pattern
we'll see be dealing with the corresponding TEMPLATE_DECL of the
local TYPE_DECL here, so we'll add the dependency).
Local classes on the other hand seem to work properly, but perhaps by
accident: with a local class we end up making the function depend on the
injected-class-name of the local class rather than the local class as a
whole because the injected-class-name satisfies the criteria (since its
context is the local class, not the function).
The 'sneakoscope' flag is set when walking a function declaration and
its purpose seems to be to catch a local type that escapes the function
via a deduced return type (so called voldemort types) and note a
dependency on them. But there seems to be no reason to restrict this
behavior to voldemort types, and indeed consistently noting the dependency
for all local types fixes these PRs (almost). So this patch gets rid of
this flag and enables the dependency tracking unconditionally.
This was nearly enough to make things work, except we now ran into
issues with the local TYPE_/CONST_DECL copies from the pre-gimplified
version of a constexpr function body during streaming. Rather than
making modules cope with this, it occurred to me that we don't need to
make copies of local types when saving the pre-gimplified body (and when
making further copies thereof); only VAR_DECLs etc need to be copied
(so that we don't conflate local variables from different recursive
calls to the same function during constexpr evaluation). So this patch
adjusts copy_fn accordingly.
PR c++/104919
PR c++/106009
gcc/cp/ChangeLog:
* module.cc (depset::hash::sneakoscope): Remove.
(trees_out::decl_node): Always add a dependency on a local type.
(depset::hash::find_dependencies): Remove sneakoscope stuff.
gcc/ChangeLog:
* tree-inline.cc (remap_decl): Handle copy_decl returning the
original decl.
(remap_decls): Handle remap_decl returning the original decl.
(copy_fn): Adjust copy_decl callback to skip TYPE_DECL and
CONST_DECL.
gcc/testsuite/ChangeLog:
* g++.dg/modules/tdef-7.h: Remove outdated comment.
* g++.dg/modules/tdef-7_b.C: Don't expect two TYPE_DECLs.
* g++.dg/modules/enum-13_a.C: New test.
* g++.dg/modules/enum-13_b.C: New test.
|