[PATCH] c++: Fix ICE from op_unqualified_lookup [PR97582]

Patrick Palka ppalka@redhat.com
Tue Feb 2 05:19:15 GMT 2021


In this testcase, we're crashing because the lookup of operator+ from
within the generic lambda via lookup_name finds multiple bindings
(namely C1::operator+ and C2::operator+) and returns a TREE_LIST
thereof, something which maybe_save_operator_binding isn't prepared to
handle.

Since we already discard the result of lookup_name when it returns a
class-scope binding here, it seems cleaner (and equivalent) to instead
communicate to lookup_name that we don't want such bindings in the first
place.  While this change seems like an improvement on its own, it also
fixes the mentioned PR, because the call to lookup_name now returns
NULL_TREE rather than a TREE_LIST of (unwanted) class-scope bindings.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk/9/10?

gcc/cp/ChangeLog:

	PR c++/97582
	* name-lookup.c (op_unqualified_lookup): Pass BLOCK_NAMESPACE to
	lookup_name in order to ignore class-scope bindings, rather
	than discarding them after the fact.

gcc/testsuite/ChangeLog:

	PR c++/97582
	* g++.dg/cpp0x/lambda/lambda-template17.C: New test.
---
 gcc/cp/name-lookup.c                                  | 11 +++--------
 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template17.C |  8 ++++++++
 2 files changed, 11 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template17.C

diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 52e4a630e25..46d6cc0dfa4 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -9213,17 +9213,12 @@ op_unqualified_lookup (tree fnname)
 	return NULL_TREE;
     }
 
-  tree fns = lookup_name (fnname);
+  /* We don't need to remember class-scope functions or declarations,
+     normal unqualified lookup will find them again.  */
+  tree fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE);
   if (!fns)
     /* Remember we found nothing!  */
     return error_mark_node;
-
-  tree d = is_overloaded_fn (fns) ? get_first_fn (fns) : fns;
-  if (DECL_CLASS_SCOPE_P (d))
-    /* We don't need to remember class-scope functions or declarations,
-       normal unqualified lookup will find them again.  */
-    fns = NULL_TREE;
-
   return fns;
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template17.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template17.C
new file mode 100644
index 00000000000..6cafbab8cb0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template17.C
@@ -0,0 +1,8 @@
+// PR c++/97582
+// { dg-do compile { target c++11 } }
+
+struct C1 { void operator+(); };
+struct C2 { void operator+(); };
+struct C3 : C1, C2 {
+  template <class T> void get() { [] (T x) { +x; }; }
+};
-- 
2.30.0.335.ge6362826a0



More information about the Gcc-patches mailing list