Bug 90480 - [8/9/10/11 Regression] ICE when calling operator() inside a lambda defined in a template class method
Summary: [8/9/10/11 Regression] ICE when calling operator() inside a lambda defined in...
Status: RESOLVED DUPLICATE of bug 95451
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.3.0
: P2 normal
Target Milestone: 8.5
Assignee: Not yet assigned to anyone
URL:
Keywords: c++-lambda, ice-on-invalid-code
Depends on:
Blocks: lambdas
  Show dependency treegraph
 
Reported: 2019-05-15 08:57 UTC by Olli Lupton
Modified: 2022-03-11 00:32 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-05-15 00:00:00


Attachments
Testcast (190 bytes, application/octet-stream)
2019-11-22 17:29 UTC, Luke Dalessandro
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Olli Lupton 2019-05-15 08:57:57 UTC
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.
Comment 1 Marek Polacek 2019-05-15 14:45:31 UTC
Started with r257093.
Comment 2 Luke Dalessandro 2019-11-22 17:26:45 UTC
I'm hitting this with the following similar, but different snippet. Maybe it will help with this.

#include <array>

struct Foo {
    int operator()(int i) {
        return 0;
    } 

    template <std::size_t N>
    auto operator()(std::array<int, N> ids) {
        return std::apply([&](auto...) {
            return operator()(0);
        }, ids);
    }
};

int main() {
    Foo foo;
    foo(std::array{0, 1});
}
Comment 3 Luke Dalessandro 2019-11-22 17:29:10 UTC
Created attachment 47336 [details]
Testcast
Comment 4 Jakub Jelinek 2020-03-04 09:32:20 UTC
GCC 8.4.0 has been released, adjusting target milestone.
Comment 5 Marek Polacek 2021-03-12 00:23:38 UTC
Dup of bug 95451 which is now fixed on trunk.

*** This bug has been marked as a duplicate of bug 95451 ***