From: Jason Merrill Date: Tue, 29 Aug 2017 19:40:55 +0000 (-0400) Subject: PR c++/80767 - unnecessary instantiation of generic lambda X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1a9de5b6b56a726313069f4447fbbbee469e99dc;p=gcc.git 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. From-SVN: r251427 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1e68776fe03..a60f2ad9679 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2017-08-29 Jason Merrill + 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 cfedd30cea3..f7f92978052 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 00000000000..75ef586b542 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/lambda-inherit1.C @@ -0,0 +1,23 @@ +// PR c++/80767 +// { dg-options -std=c++17 } + +template +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{}); +}