[Bug c++/101140] [modules] no matching function for call to ‘operator new(sizetype, void*)’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101140 --- Comment #5 from Nathaniel Shead --- (In reply to Patrick Palka from comment #4) > FWIW I was thinking we might want to perform two-phase name lookup for > new-expressions like we do for other operator expressions, wherein > unqualified lookup is performed at template definition time, saved inside > the expression (via DEPENDENT_OPERATOR_TYPE) and then reused at > instantiation time. I actually wonder if this is even correct. [basic.argdep.lookup] p4 says: > If the lookup is for a dependent name ([temp.dep], [temp.dep.candidate]), the > above lookup is also performed from each point in the instantiation context > ([module.context]) of the lookup, additionally ignoring any declaration that > appears in another translation unit, is attached to the global module, and is > either discarded ([module.global.frag]) or has internal linkage. And the instantiation context is defined to include ([module.context] p3): > ...if the template is defined in a module interface unit of a module M and > the point of instantiation is not in a module interface unit of M, the point > at the end of the declaration-seq of the primary module interface unit of M > (prior to the private-module-fragment, if any). Which implies to me that the following sample should work: export module M; export template void f(T t) { g(t); } namespace ns { export struct X {}; void g(X); } // import M; int main() { f(ns::X{}); // should compile? } but we currently error. Whether this is a sensible thing to support is another question...
[Bug c++/101140] [modules] no matching function for call to ‘operator new(sizetype, void*)’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101140 Patrick Palka changed: What|Removed |Added CC||jason at gcc dot gnu.org, ||ppalka at gcc dot gnu.org --- Comment #4 from Patrick Palka --- FWIW I was thinking we might want to perform two-phase name lookup for new-expressions like we do for other operator expressions, wherein unqualified lookup is performed at template definition time, saved inside the expression (via DEPENDENT_OPERATOR_TYPE) and then reused at instantiation time. But name lookup for a new-expression doesn't do unqualified lookup, it does qualified lookup in the global namespace ::. And unlike true two-phase name lookup which prevents operator overloads declared after the template definition from being considered, it seems GCC/Clang/MSVC all consider later-declared global operator new declarations during instantiation of a new-expression: https://godbolt.org/z/o6r9MYbKc. So it seems two-phase name lookup isn't appropriate for new-expressions, and something like your idea is the way to go? I wonder what Jason thinks.
[Bug c++/101140] [modules] no matching function for call to ‘operator new(sizetype, void*)’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101140 Nathaniel Shead changed: What|Removed |Added Status|UNCONFIRMED |NEW Ever confirmed|0 |1 CC||nshead at gcc dot gnu.org Last reconfirmed||2024-03-26 --- Comment #3 from Nathaniel Shead --- I believe this should be valid. The declaration of `::operator new` should be reachable within the instantiation context of 'construct_at' , and thus shouldn't need to be exported to be called. (See [module.context] and [module.reach].) The issue looks to be that `tsubst_expr` when handling a NEW_EXPR just calls `build_new`, which ultimately does `build_operator_new_call` that uses normal `lookup_qualified_name (global_namespace, fnname)` that doesn't consider non-exported entities. We need some way to signify that lookup should also consider declarations reachable from other points in the template's instantiation context. This could be related to one of the issues causing PR114275, but in that cases it's failing to find instantiations of friend classes in the instantiation context.
[Bug c++/101140] [modules] no matching function for call to ‘operator new(sizetype, void*)’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101140 Paul Scharnofske changed: What|Removed |Added CC||asynts+bugs at gmail dot com --- Comment #2 from Paul Scharnofske --- 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 void foo() { T t; new () T; } ``` ```c++ // bar.cpp export module bar; import foo; void bar() { foo(); } ``` ```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; | ^~ : note: candidate: 'void* operator new(long unsigned int)' : note: candidate expects 1 argument, 2 provided : note: candidate: 'void* operator new(long unsigned int, std::align_val_t)' : 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
[Bug c++/101140] [modules] no matching function for call to ‘operator new(sizetype, void*)’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101140 --- Comment #1 from ensadc at mailnesia dot com --- https://godbolt.org/z/EaPf3anxx