https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101140
--- Comment #7 from Nathaniel Shead <nshead at gcc dot gnu.org> ---
Another testcase from PR122646 that is related:
// i.cpp
export module M;
export using size_t = decltype(sizeof(0));
export inline void* operator new(size_t, void* p) { return p; }
export template <typename T> void construct_at(T* p) { ::new(p) T; }
// j.cpp
export module X;
import M;
export template <typename T> void foo(T* p) { construct_at(p); }
// k.cpp
import X;
int main() {
int result;
foo(&result);
}
$ g++ -fmodules -S [ijk].cpp
In module M, imported at j.cpp:2,
of module X, imported at k.cpp:1:
i.cpp: In instantiation of ‘void construct_at@M(T*) [with T = int]’:
required from ‘void foo@X(T*) [with T = int]’
j.cpp:6:15:
6 | construct_at(p);
| ~~~~~~~~~~~~^~~
required from here
k.cpp:4:6:
4 | foo(&result);
| ~~~^~~~~~~~~
i.cpp:4:56: error: no matching function for call to ‘operator new(sizetype,
int*&)’
4 | export template <typename T> void construct_at(T* p) { ::new(p) T; }
| ^~~~~~~~~~
• there are 2 candidates
• candidate 1: ‘void* operator new(long unsigned int)’
• candidate expects 1 argument, 2 provided
• candidate 2: ‘void* operator new(long unsigned int, std::align_val_t)’
• no known conversion for argument 2 from ‘int*’ to ‘std::align_val_t’
Which shows that the lookup_qualified_name needs to search also the
instantiation context, I suppose? See also PR122609.