[Bug c++/101140] [modules] no matching function for call to ‘operator new(sizetype, void*)’

2024-03-26 Thread nshead at gcc dot gnu.org via Gcc-bugs
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*)’

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

2024-03-26 Thread nshead at gcc dot gnu.org via Gcc-bugs
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*)’

2022-02-11 Thread asynts+bugs at gmail dot com via Gcc-bugs
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*)’

2021-09-06 Thread ensadc at mailnesia dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101140

--- Comment #1 from ensadc at mailnesia dot com ---
https://godbolt.org/z/EaPf3anxx