Tested x86_64-pc-linux-gnu. Is the diagnostic.h change OK for trunk? -- 8< --
To respect the #pragma diagnostic lines in libstdc++ headers when compiling with module std, we need to represent them in the module. I think it's reasonable to make module_state a friend of diagnostic_option_classifier to allow direct access to the data. This is a different approach from how Jakub made PCH streaming members of diagnostic_option_classifier, but it seems to me that modules handling belongs in module.cc. gcc/ChangeLog: * diagnostic.h: Add friends. gcc/cp/ChangeLog: * module.cc (module_state::write_diagnostic_classification): New. (module_state::write_begin): Call it. (module_state::read_diagnostic_classification): New. (module_state::read_initial): Call it. gcc/testsuite/ChangeLog: * g++.dg/modules/warn-spec-3_a.C: New test. * g++.dg/modules/warn-spec-3_b.C: New test. --- gcc/diagnostic.h | 4 + gcc/cp/module.cc | 86 +++++++++++++++++++- gcc/testsuite/g++.dg/modules/warn-spec-3_a.C | 20 +++++ gcc/testsuite/g++.dg/modules/warn-spec-3_b.C | 8 ++ 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/modules/warn-spec-3_a.C create mode 100644 gcc/testsuite/g++.dg/modules/warn-spec-3_b.C diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index 202760b2f85..91bde3ff06c 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -299,6 +299,8 @@ private: /* For pragma push/pop. */ vec<int> m_push_list; + + friend class module_state; }; /* A bundle of options relating to printing the user's source code @@ -807,6 +809,8 @@ private: /* The stack of sets of overridden diagnostic option severities. */ diagnostic_option_classifier m_option_classifier; + friend class module_state; + /* True if we should print any CWE identifiers associated with diagnostics. */ bool m_show_cwe; diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 78fb21dc22f..49c9c092163 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -3876,6 +3876,9 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state { void write_macro_maps (elf_out *to, range_t &, unsigned *crc_ptr); bool read_macro_maps (line_map_uint_t); + void write_diagnostic_classification (elf_out *, diagnostic_context *, unsigned *); + bool read_diagnostic_classification (diagnostic_context *); + private: void write_define (bytes_out &, const cpp_macro *); cpp_macro *read_define (bytes_in &, cpp_reader *) const; @@ -17637,6 +17640,78 @@ module_state::write_ordinary_maps (elf_out *to, range_t &info, dump.outdent (); } +/* Write out any #pragma GCC diagnostic info to the .dgc section. */ + +void +module_state::write_diagnostic_classification (elf_out *to, + diagnostic_context *dc, + unsigned *crc_p) +{ + auto &changes = dc->m_option_classifier.m_classification_history; + + dump () && dump ("Writing diagnostic change locations"); + dump.indent (); + + bytes_out sec (to); + if (sec.streaming_p ()) + sec.begin (); + + unsigned len = changes.length (); + dump () && dump ("Diagnostic changes: %u", len); + if (sec.streaming_p ()) + sec.u (len); + + for (const auto &c: changes) + { + write_location (sec, c.location); + if (sec.streaming_p ()) + { + sec.u (c.option); + sec.u (c.kind); + } + } + + if (sec.streaming_p ()) + sec.end (to, to->name (MOD_SNAME_PFX ".dgc"), crc_p); + dump.outdent (); +} + +/* Read any #pragma GCC diagnostic info from the .dgc section. */ + +bool +module_state::read_diagnostic_classification (diagnostic_context *dc) +{ + bytes_in sec; + + if (!sec.begin (loc, from (), MOD_SNAME_PFX ".dgc")) + return false; + + dump () && dump ("Reading diagnostic change locations"); + dump.indent (); + + unsigned len = sec.u (); + dump () && dump ("Diagnostic changes: %u", len); + + auto &changes = dc->m_option_classifier.m_classification_history; + unsigned offset = changes.length (); + changes.reserve (len); + for (unsigned i = 0; i < len; ++i) + { + location_t loc = read_location (sec); + int opt = sec.u (); + diagnostic_t kind = (diagnostic_t) sec.u (); + if (kind == DK_POP) + opt += offset; + changes.quick_push ({ loc, opt, kind }); + } + + dump.outdent (); + if (!sec.end (from ())) + return false; + + return true; +} + void module_state::write_macro_maps (elf_out *to, range_t &info, unsigned *crc_p) { @@ -19231,6 +19306,8 @@ module_state::write_begin (elf_out *to, cpp_reader *reader, if (is_header ()) macros = prepare_macros (reader); + write_diagnostic_classification (nullptr, global_dc, nullptr); + config.num_imports = mod_hwm; config.num_partitions = modules->length () - mod_hwm; auto map_info = write_prepare_maps (&config, bool (config.num_partitions)); @@ -19372,7 +19449,10 @@ module_state::write_begin (elf_out *to, cpp_reader *reader, /* Write the line maps. */ if (config.ordinary_locs) - write_ordinary_maps (to, map_info, bool (config.num_partitions), &crc); + { + write_ordinary_maps (to, map_info, bool (config.num_partitions), &crc); + write_diagnostic_classification (to, global_dc, &crc); + } if (config.macro_locs) write_macro_maps (to, map_info, &crc); @@ -19505,6 +19585,10 @@ module_state::read_initial (cpp_reader *reader) else if (!read_macro_maps (config.macro_locs)) ok = false; + if (ok && have_locs && config.ordinary_locs + && !read_diagnostic_classification (global_dc)) + ok = false; + /* Note whether there's an active initializer. */ active_init_p = !is_header () && bool (config.active_init); diff --git a/gcc/testsuite/g++.dg/modules/warn-spec-3_a.C b/gcc/testsuite/g++.dg/modules/warn-spec-3_a.C new file mode 100644 index 00000000000..2e50303c41e --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/warn-spec-3_a.C @@ -0,0 +1,20 @@ +// { dg-do compile { target c++20 } } +// { dg-additional-options -fmodules } +// { dg-module-cmi M } + +module; + +#include <initializer_list> + +export module M; + +#pragma GCC diagnostic ignored "-Winit-list-lifetime" + +template <class T> +struct myspan { + const T* p; unsigned s; + myspan (std::initializer_list<T> il) + : p (il.begin()), s (il.size()) { } +}; + +export void f(myspan<int>); diff --git a/gcc/testsuite/g++.dg/modules/warn-spec-3_b.C b/gcc/testsuite/g++.dg/modules/warn-spec-3_b.C new file mode 100644 index 00000000000..2a8e60af206 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/warn-spec-3_b.C @@ -0,0 +1,8 @@ +// { dg-additional-options -fmodules } + +import M; + +int main() +{ + f({24,42}); +} base-commit: fab96de044f1f023f52d43af866205d17d8895fb -- 2.47.1