aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-08-29 15:40:55 -0400
committerJason Merrill <jason@gcc.gnu.org>2017-08-29 15:40:55 -0400
commit1a9de5b6b56a726313069f4447fbbbee469e99dc (patch)
tree250e589eb24f60c22a8e42d2d51f5d1105992b63 /gcc
parentb3eae0dd176c15cf4b358ae5d93d7c3144d253fc (diff)
downloadgcc-1a9de5b6b56a726313069f4447fbbbee469e99dc.zip
gcc-1a9de5b6b56a726313069f4447fbbbee469e99dc.tar.gz
gcc-1a9de5b6b56a726313069f4447fbbbee469e99dc.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/call.c13
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/lambda-inherit1.C23
3 files changed, 39 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1e68776..a60f2ad 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 cfedd30..f7f9297 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 0000000..75ef586
--- /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{});
+}