aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/module.cc
AgeCommit message (Collapse)AuthorFilesLines
2024-09-27c++/modules: Allow imported references in constant expressionsNathaniel Shead1-1/+1
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>
2024-09-12c++/modules: Really always track partial specialisations [PR116496]Nathaniel Shead1-13/+12
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>
2024-09-09diagnostics: rename dc.printer to m_printer [PR116613]David Malcolm1-1/+1
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>
2024-09-05c++: Add missing auto_diagnostic_groupsNathaniel Shead1-0/+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>
2024-08-27c++/modules: Fix include translation for already-seen headers [PR99243]Nathaniel Shead1-5/+13
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>
2024-08-27c++/modules: Clean up include translation [PR110980]Nathaniel Shead1-9/+14
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>
2024-08-21c++/modules: Remove unnecessary errors when not writing compiled moduleNathaniel Shead1-17/+25
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>
2024-08-20c++/modules: Disable streaming definitions of non-vague-linkage GMF decls ↵Nathaniel Shead1-7/+7
[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>
2024-08-20c++/modules: Handle transitive reachability for deduction guides [PR116403]Nathaniel Shead1-6/+1
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>
2024-08-20c++/modules: Avoid rechecking initializers when streaming NTTPs [PR116382]Nathaniel Shead1-1/+5
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>
2024-08-20c++/modules: Fix type lookup in DECL_TEMPLATE_INSTANTIATIONS [PR116364]Nathaniel Shead1-1/+2
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>
2024-08-08c++/modules: Assume header bindings are global moduleNathaniel Shead1-1/+1
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>
2024-08-08c++/modules: Fix merging of GM entities in partitions [PR114950]Nathaniel Shead1-19/+33
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>
2024-08-08c++/modules: Clarify error message in read_enum_defNathaniel Shead1-2/+2
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>
2024-08-07c++/modules: Ensure deduction guides are always reachable [PR115231]Nathaniel Shead1-0/+65
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>
2024-08-06c++: permit errors inside uninstantiated templates [PR116064]Patrick Palka1-1/+4
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>
2024-07-26c++/modules: Stream warning suppressions [PR115757]Nathaniel Shead1-0/+12
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>
2024-07-18c++/modules: Conditionally start timer during lazy load [PR115165]Nathaniel Shead1-4/+4
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>
2024-07-12c++: Introduce USING_DECLs for non-function usings [PR114683]Nathaniel Shead1-30/+73
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>
2024-07-08c++: Simplify uses of LAMBDA_EXPR_EXTRA_SCOPENathaniel Shead1-5/+2
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>
2024-07-02c++: Implement C++26 P0963R3 - Structured binding declaration as a condition ↵Jakub Jelinek1-1/+1
[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.
2024-06-13c++: adjust commentJason Merrill1-3/+4
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.
2024-06-12c++: module std and exception_ptrJason Merrill1-2/+5
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.
2024-06-07c++: -include and header unit translationJason Merrill1-4/+0
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.
2024-06-01c++/modules: Fix revealing with using-decls [PR114867]Nathaniel Shead1-3/+5
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>
2024-05-25c++/modules: Improve diagnostic when redeclaring builtin in module [PR102345]Nathaniel Shead1-1/+7
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>
2024-05-25c++/modules: Remember that header units have CMIsNathaniel Shead1-2/+2
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>
2024-05-24c++/modules: Ensure all partial specialisations are tracked [PR114947]Nathaniel Shead1-4/+18
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>
2024-05-07c++/modules: Fix dangling pointer with imported_temploid_friendsNathaniel Shead1-3/+16
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>
2024-05-02c++: Don't emit unused GMF partial specializations [PR114630]Nathaniel Shead1-29/+46
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>
2024-05-02c++: Implement modules ABI for vtable emissionsNathaniel Shead1-4/+8
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>
2024-05-01c++: Propagate using decls from partitions [PR114868]Nathaniel Shead1-0/+6
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>
2024-04-30c++: Fix instantiation of imported temploid friends [PR114275]Nathaniel Shead1-0/+62
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>
2024-04-30c++: Standardise errors for module_may_redeclareNathaniel Shead1-40/+80
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>
2024-04-29c++/modules: imported spec befriending class tmpl [PR114889]Patrick Palka1-0/+2
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>
2024-04-23c++/modules: deduced return type merging [PR114795]Patrick Palka1-0/+9
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>
2024-04-15c++: Only emit exported GMF usings [PR114600]Nathaniel Shead1-1/+1
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>
2024-04-14c++: Setup aliases imported from modules [PR106820]Nathaniel Shead1-0/+9
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>
2024-04-13c++/modules: make bits_in/out move-constructiblePatrick Palka1-0/+2
gcc/cp/ChangeLog: * module.cc (struct bytes_in::bits_in): Define defaulted move ctor. (struct bytes_out::bits_out): Likewise.
2024-04-13c++/modules: optimize tree flag streamingPatrick Palka1-193/+262
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>
2024-04-12c++/modules: local type merging [PR99426]Patrick Palka1-31/+149
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>
2024-04-12c++: templated substitution into lambda-expr [PR114393]Patrick Palka1-0/+2
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>
2024-04-10c++: Track declarations imported from partitions [PR99377]Nathaniel Shead1-0/+13
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>
2024-03-13c++: Support target-specific nodes when streaming modules [PR111224]Nathaniel Shead1-10/+22
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>
2024-03-08c++: Redetermine whether to write vtables on stream-in [PR114229]Nathaniel Shead1-1/+11
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>
2024-03-07c++/modules: member alias tmpl partial inst [PR103994]Patrick Palka1-70/+16
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>
2024-03-07c++/modules: inline namespace abi_tag streaming [PR110730]Patrick Palka1-0/+28
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>
2024-03-07c++: Stream DECL_CONTEXT for template template parms [PR98881]Nathaniel Shead1-31/+10
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>
2024-03-05c++/modules: befriending template from current class scopePatrick Palka1-10/+9
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>
2024-03-01c++/modules: depending local enums [PR104919, PR106009]Patrick Palka1-10/+2
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.