[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 Nathaniel Shead changed: What|Removed |Added Resolution|--- |FIXED CC||nshead at gcc dot gnu.org Status|REOPENED|RESOLVED --- Comment #18 from Nathaniel Shead --- Fixed in GCC 14.
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #17 from GCC Commits --- The master branch has been updated by Nathaniel Shead : https://gcc.gnu.org/g:77c0b5b23f91404004a9bf710981f6d615b63f57 commit r14-9881-g77c0b5b23f91404004a9bf710981f6d615b63f57 Author: Nathaniel Shead Date: Thu Apr 4 23:16:08 2024 +1100 c++: Track declarations imported from partitions [PR99377] 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 (); } } 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
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 Patrick Palka changed: What|Removed |Added Last reconfirmed|2021-03-04 00:00:00 |2024-3-6 --- Comment #16 from Patrick Palka --- The comment #15 testcase still fails on trunk.
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 Patrick Palka changed: What|Removed |Added CC||ppalka at gcc dot gnu.org --- Comment #15 from Patrick Palka --- The comment #5 testcase now works on trunk, but the comment #4 testcase still fails to link. Reduced: $ cat 99377_a.H template struct Widget { Widget (int) { } bool First() const { return true; } bool Second () const { return true;} }; inline void Frob (const Widget& w) noexcept { w.First (); } $ 99377_b.C export module Foo:check; import "99377_a.H"; export inline bool Check (const Widget& w) { return w.Second (); } $ cat 99377_c.C export module Foo; export import :check; $ cat 99377_d.C import Foo; int main () { return Check (0) ? 0 : 1; } $ g++ -fmodules-ts 99377_a.H 99377_b.C 99377_c.C 99377_d.C /usr/bin/ld: /tmp/ccBHt33S.o: in function `Check@Foo(Widget const&)': 99377_d.C:(.text._ZW3Foo5CheckRK6WidgetIiE[_ZW3Foo5CheckRK6WidgetIiE]+0x14): undefined reference to `Widget::Second() const'
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #14 from CVS Commits --- The master branch has been updated by Patrick Palka : https://gcc.gnu.org/g:2ceb4d531a303f3e70d8bb218c8759e6c0688f62 commit r13-3235-g2ceb4d531a303f3e70d8bb218c8759e6c0688f62 Author: Patrick Palka Date: Tue Oct 11 15:02:01 2022 -0400 c++ modules: lazy loading from within template [PR99377] Here when lazily loading the binding for f due to its first use from the template g, processing_template_decl is set which causes the call to note_vague_linkage_fn from module_state::read_cluster to have no effect, and thus we never push f onto deferred_fns and end up never emitting its definition despite needing it. The behavior of the lazy loading machinery shouldn't be sensitive to whether we're inside a template, so to that end this patch makes us clear processing_template_decl in the entrypoints lazy_load_binding and lazy_load_pendings. PR c++/99377 gcc/cp/ChangeLog: * module.cc (lazy_load_binding): Clear processing_template_decl. (lazy_load_pendings): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/pr99377-2_a.C: New test. * g++.dg/modules/pr99377-2_b.C: New test.
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #13 from Johel Ernesto Guerrero Peña --- > The workaround of Comment 5 stopped working for my actual use-case some time > ago. The `using` declaration works if I move it earlier in the TU.
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #12 from Johel Ernesto Guerrero Peña --- The workaround of Comment 5 stopped working for my actual use-case some time ago. Now I do this: ```C++ export constexpr void expects(bool truth) noexcept { if (not truth) std::terminate(); } // Workarounds GCC bug 99377. export constexpr auto expects2 = expects; ``` FWIW, I've attached the debug and release `.gcm` and `.o` (without the workaround above), which might hint as to what's (not) happening.
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #11 from Johel Ernesto Guerrero Peña --- Created attachment 53312 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53312=edit Release object file
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #10 from Johel Ernesto Guerrero Peña --- Created attachment 53311 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53311=edit Release GCM
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #9 from Johel Ernesto Guerrero Peña --- Created attachment 53310 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53310=edit Debug object file
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #8 from Johel Ernesto Guerrero Peña --- Created attachment 53309 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53309=edit Debug GCM
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #7 from Johel Ernesto Guerrero Peña --- if (v == [] consteval { return std::numeric_limits::max() }()) break; works too. More generally, you can avoid the linker error if you don't require the symbol at link time.
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #6 from Johel Ernesto Guerrero Peña --- A workaround for static member functions: ```C++ template [[nodiscard]] consteval I max() { return std::numeric_limits::max(); } if (v == std::numeric_limits::max()) break; if (v == max()) break; ```
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 Johel Ernesto Guerrero Peña changed: What|Removed |Added CC||johelegp at gmail dot com --- Comment #5 from Johel Ernesto Guerrero Peña --- I get the same error in this case in debug mode: https://godbolt.org/z/zEGTcMhbh. mod.cpp: ```C++ export module mod; export inline void f() {} ``` test.cpp: ```C++ import mod; // using ::f; // Workaround GCC bug 99377. template void g() { f(); } int main() { g(); } ``` Commands: ``` g++ -pedantic -Wall -Wextra -Wconversion -g -fmodules-ts -std=c++23 -c mod.cpp g++ -pedantic -Wall -Wextra -Wconversion -g -fmodules-ts -std=c++23 -c test.cpp g++ -pedantic -Wall -Wextra -Wconversion -g -fmodules-ts -std=c++23 *.o ``` Output: ``` /usr/bin/ld: test.o: in function `void g()': /home/johel/tmp/bug/test.cpp:3: undefined reference to `f()' collect2: error: ld returned 1 exit status ```
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 Boris Kolpackov changed: What|Removed |Added Status|RESOLVED|REOPENED Resolution|FIXED |--- --- Comment #4 from Boris Kolpackov --- I still get the same error if I move the inline function into an interface partition (main.cxx is unchanged): cat
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 Nathan Sidwell changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --- Comment #3 from Nathan Sidwell --- 1e5cdb9f896 2021-03-05 | c++: Local instantiations of imported specializations [PR 99377]
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #2 from CVS Commits --- The master branch has been updated by Nathan Sidwell : https://gcc.gnu.org/g:1e5cdb9f896fb220b26fd2080406504c4badf5af commit r11-7530-g1e5cdb9f896fb220b26fd2080406504c4badf5af Author: Nathan Sidwell Date: Fri Mar 5 10:34:23 2021 -0800 c++: Local instantiations of imported specializations [PR 99377] This turned out to be the function version of the previous fix. We can import an implicit specialization declaration that we need to instantiate. We must mark the instantiation so we remember to stream it. PR c++/99377 gcc/cp/ * pt.c (instantiate_decl): Call set_instantiating_module. gcc/testsuite/ * g++.dg/modules/pr99377_a.H: New. * g++.dg/modules/pr99377_b.C: New. * g++.dg/modules/pr99377_c.C: New.
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 --- Comment #1 from Nathan Sidwell --- // bug_a.ii template struct Widget { Widget (int) { } bool First() const { return true; } bool Second () const { return true;} }; inline void Frob (const Widget& w) noexcept { w.First (); } // bug_b.ii export module Foo; import "bug_a.ii"; export inline bool Check (const Widget& w) { return w.Second (); } // bug_c.ii import Foo; int main () { return Check (0) ? 0 : 1; } ./cc1plus -fmodule-header -quiet bug_a.ii && ./cc1plus -quiet -fmodules-ts bug_b.ii && ./cc1plus -quiet -fmodules-ts bug_c.ii && g++ bug_b.s bug_c.s /data/users/nathans/tools/lib/gcc/x86_64-pc-linux-gnu/10.1.1/../../../../x86_64-pc-linux-gnu/bin/ld: /tmp/cc6QqMLl.o: in function `Check(Widget const&)': bug_c.ii:(.text._Z5CheckRK6WidgetIiE[_Z5CheckRK6WidgetIiE]+0x14): undefined reference to `Widget::Second() const' collect2: error: ld returned 1 exit status
[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99377 Nathan Sidwell changed: What|Removed |Added Last reconfirmed||2021-03-04 Ever confirmed|0 |1 Status|UNCONFIRMED |ASSIGNED