https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101140

Paul Scharnofske <asynts+bugs at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |asynts+bugs at gmail dot com

--- Comment #2 from Paul Scharnofske <asynts+bugs at gmail dot com> ---
I had a very similar problem:

```c++
// foo.cpp
export module foo;

using size_t = decltype(sizeof(int));

void* operator new(size_t, void *pointer) {
    return pointer;
}

export
template<typename T>
void foo() {
    T t;
    new (&t) T;
}
```
```c++
// bar.cpp
export module bar;

import foo;

void bar() {
    foo<int>();
}
```
```c++
// main.cpp
export module main;

import foo;
import bar;

int main() {

}
```
```none
$ ~/.local/lib/gcc-trunk/bin/g++ --version
g++ (GCC) 12.0.1 20220211 (experimental)
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ~/.local/lib/gcc-trunk/bin/g++ -Wall -Wextra -std=c++20 -fmodules-ts foo.cpp
bar.cpp main.cpp
In module foo, imported at bar.cpp:4:
foo.cpp: In instantiation of 'void foo@foo() [with T = int]':
bar.cpp:7:13:   required from here
foo.cpp:14:5: error: no matching function for call to 'operator new(sizetype,
int*)'
   14 |     new (&t) T;
      |     ^~~~~~~~~~
<built-in>: note: candidate: 'void* operator new(long unsigned int)'
<built-in>: note:   candidate expects 1 argument, 2 provided
<built-in>: note: candidate: 'void* operator new(long unsigned int,
std::align_val_t)'
<built-in>: note:   no known conversion for argument 2 from 'int*' to
'std::align_val_t'
bar.cpp:2:8: warning: not writing module 'bar' due to errors
    2 | export module bar;
      |        ^~~~~~
In module imported at main.cpp:5:1:
bar: error: failed to read compiled module: No such file or directory
bar: note: compiled module file is 'gcm.cache/bar.gcm'
bar: note: imports must be built before being imported
bar: fatal error: returning to the gate for a mechanical issue
compilation terminated.
```
https://godbolt.org/z/es5he4hc4

It appears that the compiler tries to lookup the placement new operator in the
module
where the template instantiation happens.
In my mind, the correct behavior would be to look this up in the module where
the
template is defined.
However, I am not familiar with the standard.

There are several ways, this code can be changed to work:

 1. Add 'export' to the 'operator new'.
    However, this requires that the module that defines the operator new is
imported
    by the module directly.
    https://godbolt.org/z/nxY681PeK

 2. Remove the template parameter from 'foo'.
    https://godbolt.org/z/1T9Erjdz3

Reply via email to