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 <typename T>
struct Struct {
    void operator()( int x, int y ) { }
    void foo() {
        [this]( auto x ){ operator()( x, x ); }( 42 );
    }
};

int main()
{
    Struct<int> x;
    x.foo();
    return 0;
}

the error (with gcc 8.3.0) is:

<source>: In instantiation of 'void Struct<T>::foo() [with T = int]':
<source>:12:11:   required from here
<source>: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:

<source>: In instantiation of 'Struct<T>::foo()::<lambda(auto:1)> [with auto:1
= int; T = int]':
<source>:5:48:   required from 'void Struct<T>::foo() [with T = int]'
<source>:12:11:   required from here
<source>:5:37: error: no matching function for call to 'Struct<T>::foo() [with
T = int]::<lambda(auto:1)>::operator()(int&, int&) const'
         [this]( auto x ){ operator()( x, x ); }( 42 );
                           ~~~~~~~~~~^~~~~~~~
<source>:5:24: note: candidate: template<class auto:1>
Struct<T>::foo()::<lambda(auto:1)> [with auto:1 = auto:1; T = int]
         [this]( auto x ){ operator()( x, x ); }( 42 );
                        ^
<source>:5:24: note:   template argument deduction/substitution failed:
<source>: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.

Reply via email to