[Bug c++/99377] [modules] undefined std::string_view::empty() if referenced in inline exported function

2024-04-09 Thread nshead at gcc dot gnu.org via Gcc-bugs
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

2024-04-09 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
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

2024-03-06 Thread ppalka at gcc dot gnu.org via Gcc-bugs
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

2022-10-12 Thread ppalka at gcc dot gnu.org via Gcc-bugs
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

2022-10-11 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
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

2022-07-17 Thread johelegp at gmail dot com via Gcc-bugs
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

2022-07-16 Thread johelegp at gmail dot com via Gcc-bugs
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

2022-07-16 Thread johelegp at gmail dot com via Gcc-bugs
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

2022-07-16 Thread johelegp at gmail dot com via Gcc-bugs
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

2022-07-16 Thread johelegp at gmail dot com via Gcc-bugs
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

2022-07-16 Thread johelegp at gmail dot com via Gcc-bugs
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

2021-12-20 Thread johelegp at gmail dot com via Gcc-bugs
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

2021-11-29 Thread johelegp at gmail dot com via Gcc-bugs
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

2021-11-29 Thread johelegp at gmail dot com via Gcc-bugs
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

2021-03-30 Thread boris at kolpackov dot net via Gcc-bugs
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

2021-03-05 Thread nathan at gcc dot gnu.org via Gcc-bugs
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

2021-03-05 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
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

2021-03-05 Thread nathan at gcc dot gnu.org via Gcc-bugs
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

2021-03-04 Thread nathan at gcc dot gnu.org via Gcc-bugs
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