Bug 63628 - [c++1y] cannot use decltype on captured arg-pack
Summary: [c++1y] cannot use decltype on captured arg-pack
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.0
: P3 normal
Target Milestone: 6.0
Assignee: Not yet assigned to anyone
URL:
Keywords: c++-lambda, ice-on-valid-code, rejects-valid
: 61814 (view as bug list)
Depends on:
Blocks: lambdas
  Show dependency treegraph
 
Reported: 2014-10-23 12:39 UTC by Jonathan Wakely
Modified: 2022-03-11 00:32 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-10-23 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2014-10-23 12:39:31 UTC
+++ This bug was initially created as a clone of Bug #61814 +++

The code below has a lambda that captures the outer params t, for forwarding matter, decltype on t has to be used.
```
    auto const pack = [](auto&&... t)
    {
        return [&](auto&& f)->decltype(auto)
        {
            return f(static_cast<decltype(t)>(t)...);
        };
    };
    
    int main(int argc, char** argv) {
        pack(1)([](int){});
        return 0;
    }
```
It works with clang 3.5, but g++ 4.9.0 complains:
error: 't' was not declared in this scope

The same also applies to `sizeof` or that kind of compile-time thing.
Comment 1 Jonathan Wakely 2014-10-23 12:41:17 UTC
This still fails on trunk, reduced from the original code in PR 61814

    auto const pack = [](auto... t)
    {
        [&]
        {
           int a[] = { static_cast<decltype(t)>(t)... };
        };
    };
    
    int main() {
        pack(1);
    }

ll.cc: In instantiation of ‘<lambda(auto:1 ...)>::<lambda()> [with auto:1 = {int}]’:
ll.cc:5:49:   required from ‘struct<lambda(auto:1 ...)> [with auto:1 = {int}]::<lambda()>’
ll.cc:3:9:   required from ‘<lambda(auto:1 ...)> [with auto:1 = {int}]’
ll.cc:10:15:   required from here
ll.cc:5:55: error: cannot convert ‘decltype (t)’ to ‘int’ in initialization
            int a[] = { static_cast<decltype(t)>(t)... };
                                                       ^
ll.cc:5:55: error: storage size of ‘a’ isn’t known
Comment 2 Jonathan Wakely 2014-10-23 12:43:40 UTC
And this variation gives an ICE:

    void sink(...) { }

    auto const pack = [](auto... t)
    {
        [&]
        {
           sink( static_cast<decltype(t)>(t)... );
        };
    };
    
    int main() {
        pack(1);
    }

ll.cc: In instantiation of ‘<lambda(auto:1 ...)>::<lambda()> [with auto:1 = {int}]’:
ll.cc:7:43:   required from ‘struct<lambda(auto:1 ...)> [with auto:1 = {int}]::<lambda()>’
ll.cc:5:9:   required from ‘<lambda(auto:1 ...)> [with auto:1 = {int}]’
ll.cc:12:15:   required from here
ll.cc:7:16: internal compiler error: in cxx_incomplete_type_diagnostic, at cp/typeck2.c:572
            sink( static_cast<decltype(t)>(t)... );
                ^
0x615fb9 cxx_incomplete_type_diagnostic(tree_node const*, tree_node const*, diagnostic_t)
        /home/jwakely/src/gcc/gcc/cp/typeck2.c:572
0x6ba1c4 complete_type_or_maybe_complain(tree_node*, tree_node*, int)
        /home/jwakely/src/gcc/gcc/cp/typeck.c:153
0x6ba279 require_complete_type_sfinae(tree_node*, int)
        /home/jwakely/src/gcc/gcc/cp/typeck.c:90
0x552061 convert_arg_to_ellipsis(tree_node*, int)
        /home/jwakely/src/gcc/gcc/cp/call.c:6565
0x557e37 build_over_call
        /home/jwakely/src/gcc/gcc/cp/call.c:7265
0x56dfcb build_new_function_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, int)
        /home/jwakely/src/gcc/gcc/cp/call.c:4072
0x71c5cc finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, bool, int)
        /home/jwakely/src/gcc/gcc/cp/semantics.c:2361
0x6b9b86 complete_type(tree_node*)
        /home/jwakely/src/gcc/gcc/cp/typeck.c:134
0x6506a5 mark_used(tree_node*, int)
        /home/jwakely/src/gcc/gcc/cp/decl2.c:4936
0x55870b build_over_call
        /home/jwakely/src/gcc/gcc/cp/call.c:7411
0x56bf2b build_op_call_1
        /home/jwakely/src/gcc/gcc/cp/call.c:4303
0x56bf2b build_op_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**, int)
        /home/jwakely/src/gcc/gcc/cp/call.c:4326
0x71c513 finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool, bool, int)
        /home/jwakely/src/gcc/gcc/cp/semantics.c:2378
0x7e4e82 c_common_parse_file()
        /home/jwakely/src/gcc/gcc/c-family/c-opts.c:1050
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
Comment 3 Paolo Carlini 2015-12-15 10:26:06 UTC
The second and third variants work in mainline.
Comment 4 Jason Merrill 2015-12-15 16:46:11 UTC
(In reply to Paolo Carlini from comment #3)
> The second and third variants work in mainline.

Yes, they were fixed by the patch for bug 68309.  We need a further fix to handle the original testcase.
Comment 5 Jason Merrill 2015-12-16 18:22:49 UTC
Author: jason
Date: Wed Dec 16 18:22:17 2015
New Revision: 231713

URL: https://gcc.gnu.org/viewcvs?rev=231713&root=gcc&view=rev
Log:
	PR c++/63628
	* pt.c (tsubst_pack_expansion): Also make dummy decls if
	retrieve_local_specialization fails.

Added:
    trunk/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic3.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
Comment 6 Jason Merrill 2015-12-16 18:23:04 UTC
Fixed.
Comment 7 Jason Merrill 2015-12-16 18:23:23 UTC
*** Bug 61814 has been marked as a duplicate of this bug. ***
Comment 8 Jason Merrill 2015-12-16 18:37:27 UTC
Author: jason
Date: Wed Dec 16 18:36:55 2015
New Revision: 231715

URL: https://gcc.gnu.org/viewcvs?rev=231715&root=gcc&view=rev
Log:
	PR c++/63628
	* pt.c (tsubst_pack_expansion): Also make dummy decls if
	retrieve_local_specialization fails.

Added:
    branches/gcc-5-branch/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic3.C
Modified:
    branches/gcc-5-branch/gcc/cp/ChangeLog
    branches/gcc-5-branch/gcc/cp/pt.c