Bug 77585 - g++ incorrectly decides that member function is called without object in generic lambda
Summary: g++ incorrectly decides that member function is called without object in gene...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.1.1
: P3 normal
Target Milestone: ---
Assignee: Nathan Sidwell
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2016-09-14 00:22 UTC by neil.attn
Modified: 2022-02-02 04:50 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2016-12-14 00:00:00


Attachments
smaller testcase (145 bytes, text/plain)
2016-12-14 13:50 UTC, Nathan Sidwell
Details
Let's try that again ... (126 bytes, text/plain)
2016-12-14 13:53 UTC, Nathan Sidwell
Details

Note You need to log in before you can comment on or make changes to this bug.
Description neil.attn 2016-09-14 00:22:31 UTC
I think I've found a bug regarding generic lambdas in g++. Clang accepts code.
$ cat gcc_maybe_bug.cc 
#include <algorithm>
#include <iterator>
#include <iostream>

template <typename T>
struct Base
{
        using value_type = T;

        void func(T v)
        {
                std::cout << v << a << '\n';
        }

        T a{5};
};

template <typename T>
struct Derived : T
{
        using typename T::value_type;

        // here's the bug, maybe?
        void do_something()
        {
                // Call member function of the base class. Everything's fine.
                T::func(arr[0]);

                // Everything is fine here also:
                auto lambda = [this](auto a) { T::func(a); };
                lambda(arr[1]);

                // Everything's fine here, too. Non-generic lambda.
                std::for_each(std::begin(arr), std::end(arr), [this](int a) { T::func(a); });

                // Here's the error: g++ thinks, that T::func(a) is a call without object, even
                // though "this" is explicitly captured. Same as above, but generic lambda.
                std::for_each(std::begin(arr), std::end(arr), [this](auto a) { T::func(a); });
        }

        value_type arr[16]{};
};

int main()
{
        Derived<Base<int>> o;
        o.do_something();
        return 0;
}
$ g++ -std=c++14 -Wall -Wextra -pedantic gcc_maybe_bug.cc 
gcc_maybe_bug.cc: In instantiation of ‘Derived<T>::do_something()::<lambda(auto:2)> [with auto:2 = int; T = Base<int>]’:
/usr/include/c++/6.1.1/bits/stl_algo.h:3769:5:   required from ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = int*; _Funct = Derived<T>::do_something() [with T = Base<int>]::<lambda(auto:2)>]’
gcc_maybe_bug.cc:38:30:   required from ‘void Derived<T>::do_something() [with T = Base<int>]’
gcc_maybe_bug.cc:47:24:   required from here
gcc_maybe_bug.cc:38:87: error: cannot call member function ‘void Base<T>::func(T) [with T = int]’ without object
                 std::for_each(std::begin(arr), std::end(arr), [this](auto a) { T::func(a); });

$ g++ --version
g++ (GCC) 6.1.1 20160621 (Red Hat 6.1.1-3)
Copyright (C) 2016 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.
$ clang++ -std=c++14 -Wall -Wextra -pedantic gcc_maybe_bug.cc
Comment 1 Nathan Sidwell 2016-12-14 13:50:15 UTC
Created attachment 40336 [details]
smaller testcase

I independently reduced an exemplar to the attached testcase.  The necessary condition is that the lambda is defined within the argument list of the function it is being passed to.
Comment 2 Nathan Sidwell 2016-12-14 13:53:40 UTC
Created attachment 40337 [details]
Let's try that again ...
Comment 3 Nathan Sidwell 2016-12-15 19:50:57 UTC
Author: nathan
Date: Thu Dec 15 19:50:25 2016
New Revision: 243723

URL: https://gcc.gnu.org/viewcvs?rev=243723&root=gcc&view=rev
Log:
	PR c++/77585
	* pt.c (instantiate_decl): Push to class scope lambda resides
	within when instantiating a generic lambda function.

	PR c++/77585
	* g++.dg/cpp1y/pr77585.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/cpp1y/pr77585.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
    trunk/gcc/testsuite/ChangeLog
Comment 4 Nathan Sidwell 2016-12-15 19:51:32 UTC
Fixed on trunk