Bug 78816 - [c++14] Static auto variable usage in generic/variadic lambda fails to compile
Summary: [c++14] Static auto variable usage in generic/variadic lambda fails to compile
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.2.1
: P3 normal
Target Milestone: 8.0
Assignee: Not yet assigned to anyone
URL:
Keywords: c++-lambda
Depends on:
Blocks: lambdas
  Show dependency treegraph
 
Reported: 2016-12-14 18:20 UTC by Jeroen De Busser
Modified: 2022-03-11 00:32 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jeroen De Busser 2016-12-14 18:20:07 UTC
Sample code adapted from https://adishavit.github.io/2016/Technical-Debt/ (https://godbolt.org/g/osKPbq):
void f(void (*f1)(int)) {
  f1(42);
}

//Converts any lambda to a captureless lambda that converts nicely to a function pointer for the lifetime of the temporary.
template <typename Lambda>
static auto callback(Lambda &&l)
{
  static auto* p = &l;
  p = &l;
  return [](auto... x){ return (*p)(x...); };
}

int main() {
  int x = 5;
  f(callback([=](int y){std::cout << x << ' ' << y;}));
}

Gives the error:
<source>: In instantiation of 'callback(Lambda&&)::<lambda(auto:1 ...)> [with auto:1 = {int}; Lambda = main()::<lambda(int)>]':
<source>:14:22:   required by substitution of 'template<class ... auto:1> callback(Lambda&&) [with Lambda = main()::<lambda(int)>]::<lambda(auto:1 ...)>::operator decltype (((const callback(Lambda&&) [with Lambda = main()::<lambda(int)>]::<lambda(auto:1 ...)>*)((const callback(Lambda&&) [with Lambda = main()::<lambda(int)>]::<lambda(auto:1 ...)>* const)0u))->operator()(static_cast<auto:1&>(callback::__lambda0<main::__lambda1>::_FUN::<unnamed>) ...)) (*)(auto:1 ...)() const [with auto:1 = {int}]'
<source>:19:54:   required from here
<source>:14:33: error: use of 'p' before deduction of 'auto'
return [](auto... x){ return (*p)(x...); };
~^~~
<source>:14:36: error: invalid use of 'auto'
return [](auto... x){ return (*p)(x...); };
~~~~^~~~~~

Making the lambda in callback non-generic(ie: [](int x){return (*p)(x);}) or explicitly calculating the type of p(std::add_pointer_t<decltype(l)>) makes the code compile successfully.
Comment 1 paolo@gcc.gnu.org 2017-10-04 08:35:12 UTC
Author: paolo
Date: Wed Oct  4 08:34:40 2017
New Revision: 253397

URL: https://gcc.gnu.org/viewcvs?rev=253397&root=gcc&view=rev
Log:
2017-10-04  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/78816
	* g++.dg/cpp1y/lambda-generic-variadic6.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic6.C
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 2 Paolo Carlini 2017-10-04 08:35:41 UTC
Fixed in trunk.