diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1e68776fe03eb044ecdbca6b81f646899e5d9432..a60f2ad9679ef959220076b9f1a8e2e2509ff2d2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2017-08-29 Jason Merrill <jason@redhat.com> + PR c++/80767 - unnecessary instantiation of generic lambda + * call.c (convert_like_real): Call build_user_type_conversion_1 if + cand is null. + (add_conv_candidate): Build a ck_user conversion with no candidate. + Fix lambdas in template default argument of inherited ctor. * method.c (synthesized_method_base_walk): Replace an inherited template with its specialization. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index cfedd30cea35a18f58297ae6db23c1c81a1ee04d..f7f929780529d290fcd9e2de4a8f190e9ef5f93e 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -2278,8 +2278,10 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, if (i == 0) { - t = implicit_conversion (totype, argtype, arg, /*c_cast_p=*/false, - flags, complain); + t = build_identity_conv (argtype, NULL_TREE); + t = build_conv (ck_user, totype, t); + /* Leave the 'cand' field null; we'll figure out the conversion in + convert_like_real if this candidate is chosen. */ convert_type = totype; } else if (parmnode == void_list_node) @@ -6692,6 +6694,13 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, case ck_user: { struct z_candidate *cand = convs->cand; + + if (cand == NULL) + /* We chose the surrogate function from add_conv_candidate, now we + actually need to build the conversion. */ + cand = build_user_type_conversion_1 (totype, expr, + LOOKUP_NO_CONVERSION, complain); + tree convfn = cand->fn; /* When converting from an init list we consider explicit diff --git a/gcc/testsuite/g++.dg/cpp1z/lambda-inherit1.C b/gcc/testsuite/g++.dg/cpp1z/lambda-inherit1.C new file mode 100644 index 0000000000000000000000000000000000000000..75ef586b542e366c72c81fafe493b74ed7ef3d9c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/lambda-inherit1.C @@ -0,0 +1,23 @@ +// PR c++/80767 +// { dg-options -std=c++17 } + +template <typename... Fs> +struct overloader : Fs... +{ + overloader(Fs... fs) + : Fs(fs)... + { } + + using Fs::operator()...; +}; + +struct a { void foo() { } }; +struct b { void bar() { } }; +struct c { void bar() { } }; + +int main() { + overloader{ + [](a x) { x.foo(); }, + [](auto x) { x.bar(); } + }(a{}); +}