https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90480
Bug ID: 90480
Summary: ICE when calling operator() inside a lambda defined in
a template class method
Product: gcc
Version: 8.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: gcc at olupton dot com
Target Milestone: ---
In gcc versions 8 and above (tested 8.1.0, 8.2.0, 8.3.0, 9.1.0 and trunk
available on godbolt compiler explorer, plus 8.3.0 installed via MacPorts on
MacOS), the following code produces an internal compiler error (using
-std=c++17):
template
struct Struct {
void operator()( int x, int y ) { }
void foo() {
[this]( auto x ){ operator()( x, x ); }( 42 );
}
};
int main()
{
Struct x;
x.foo();
return 0;
}
the error (with gcc 8.3.0) is:
: In instantiation of 'void Struct::foo() [with T = int]':
:12:11: required from here
:5:27: internal compiler error: in lookup_template_class_1, at
cp/pt.c:9459
[this]( auto x ){ operator()( x, x ); }( 42 );
^~~~
in older versions of gcc (5 through 7) an informative error was given:
: In instantiation of 'Struct::foo():: [with auto:1
= int; T = int]':
:5:48: required from 'void Struct::foo() [with T = int]'
:12:11: required from here
:5:37: error: no matching function for call to 'Struct::foo() [with
T = int]operator()(int&, int&) const'
[this]( auto x ){ operator()( x, x ); }( 42 );
~~^~~~
:5:24: note: candidate: template
Struct::foo():: [with auto:1 = auto:1; T = int]
[this]( auto x ){ operator()( x, x ); }( 42 );
^
:5:24: note: template argument deduction/substitution failed:
:5:37: note: candidate expects 1 argument, 2 provided
[this]( auto x ){ operator()( x, x ); }( 42 );
~~^~~~
Compiler returned: 1
In clang (5,6,7,8,trunk) the code compiles.
If the call to operator() inside the lambda is explicitly prefixed with this->
then the code compiles with all compilers/versions mentioned above.
The issue seems to be to do with the operator() method of the lambda itself
entering the overload resolution (?). If operator() is replaced with operator[]
everywhere in the example code given, i.e.
void operator[]( int x ) { }
void foo() {
[this]( auto x ){ operator[]( x ); }( 42 );
}
there is no error.
Live example: https://godbolt.org/z/DyShsR
As there are no preprocessor directives, I have not included a preprocessed
file. The compiler explorer link, I hope, documents many of the
system+version+gcc build flags that can be used to reproduce the error, but for
completeness I also include the -v information from my local machine:
$ g++-mp-8 -v
Using built-in specs.
COLLECT_GCC=g++-mp-8
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin18/8.3.0/lto-wrapper
Target: x86_64-apple-darwin18
Configured with:
/opt/local/var/macports/build/_opt_bblocal_var_buildworker_ports_build_ports_lang_gcc8/gcc8/work/gcc-8.3.0/configure
--prefix=/opt/local --build=x86_64-apple-darwin18
--enable-languages=c,c++,objc,obj-c++,lto,fortran --libdir=/opt/local/lib/gcc8
--includedir=/opt/local/include/gcc8 --infodir=/opt/local/share/info
--mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-8
--with-local-prefix=/opt/local --with-system-zlib --disable-nls
--program-suffix=-mp-8 --with-gxx-include-dir=/opt/local/include/gcc8/c++/
--with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local
--with-isl=/opt/local --enable-stage1-checking --disable-multilib --enable-lto
--enable-libstdcxx-time --with-build-config=bootstrap-debug
--with-as=/opt/local/bin/as --with-ld=/opt/local/bin/ld
--with-ar=/opt/local/bin/ar --with-bugurl=https://trac.macports.org/newticket
--disable-tls --with-pkgversion='MacPorts gcc8 8.3.0_4'
--with-sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk
Thread model: posix
gcc version 8.3.0 (MacPorts gcc8 8.3.0_4)
But I have seen no indication that this is tied to the platform etc.