From: Jason Merrill Date: Fri, 24 Jan 2020 23:20:56 +0000 (-0500) Subject: c++: Fix ICE with lambda in member operator (PR93279) X-Git-Tag: releases/gcc-9.3.0~178 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7db777843ccba2596f3aa1817edc50156afe2fc3;p=thirdparty%2Fgcc.git c++: Fix ICE with lambda in member operator (PR93279) Here the problem was that we were remembering the lookup in template scope, and then trying to reuse that lookup in the instantiation without substituting into it at all. The simplest solution is to not try to remember a lookup that finds a class-scope declaration, as in that case doing the normal lookup again at instantiation time will always find the right declarations. PR c++/93279 - ICE with lambda in member operator. * name-lookup.c (maybe_save_operator_binding): Don't remember class-scope bindings. --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 69efbb99af47..d8fc647120e0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-01-28 Jason Merrill + + PR c++/93279 - ICE with lambda in member operator. + * name-lookup.c (maybe_save_operator_binding): Don't remember + class-scope bindings. + 2020-01-27 Nathan Sidwell PR c++/91826 diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 7b5ae9d3990d..8999c5ad4a74 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -7626,6 +7626,12 @@ maybe_save_operator_binding (tree e) if (!fns && (fns = op_unqualified_lookup (fnname))) { + tree fn = get_first_fn (fns); + if (DECL_CLASS_SCOPE_P (fn)) + /* We don't need to remember class-scope functions, normal unqualified + lookup will find them again. */ + return; + bindings = tree_cons (fnname, fns, bindings); if (attr) TREE_VALUE (attr) = bindings; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template16.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template16.C new file mode 100644 index 000000000000..faaff68b968f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template16.C @@ -0,0 +1,15 @@ +// PR c++/93279 +// { dg-do compile { target c++11 } } + +template struct B { using f = int; }; +template struct E { + template ::f = 0> + void operator*(U l) { [l](T m) { m * l; }; } +}; + +int +main () +{ + E, 1> n; + n * 4.f; +}