diff mbox series

[PR,c++/84434] ICE with deduction guide

Message ID 30446d31-fe5e-1dc5-6c16-27454978e6db@acm.org
State New
Headers show
Series [PR,c++/84434] ICE with deduction guide | expand

Commit Message

Nathan Sidwell March 1, 2018, 9:37 p.m. UTC
This crash was caused by unexpectedly seeing a USING_DECL.  Normally we 
want to make dependent using-decls visible to name lookup, so we know to 
defer things to instantiation time.  But here we're (a) explicitly 
looking inside uninstantiated templates and (b) want to know the ctors 
the template definitely has.  so we should ignore the dependent 
inherited ctor.

Before my name reworking, the lookup during the deduction guide 
generation never saw the using decl, as it never made it into the 
special CONSTRUCTOR_SLOT.

nathan
diff mbox series

Patch

2018-03-01  Nathan Sidwell  <nathan@acm.org>

	PR c++/84434
	* name-lookup.c (member_vec_dedup): Remove manually peeled
	iteration.  Ignore dependent ctor inheritance.

	PR c++/84434
	* g++.dg/template/pr84434.C: New.

Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 258100)
+++ cp/name-lookup.c	(working copy)
@@ -1591,68 +1591,58 @@  member_vec_dedup (vec<tree, va_gc> *memb
   if (!len)
     return;
 
-  tree current = (*member_vec)[0], name = OVL_NAME (current);
-  tree next = NULL_TREE, next_name = NULL_TREE;
-  for (unsigned jx, ix = 0; ix < len;
-       ix = jx, current = next, name = next_name)
+  tree name = OVL_NAME ((*member_vec)[0]);
+  for (unsigned jx, ix = 0; ix < len; ix = jx)
     {
+      tree current = NULL_TREE;
       tree to_type = NULL_TREE;
       tree to_using = NULL_TREE;
       tree marker = NULL_TREE;
-      if (IDENTIFIER_CONV_OP_P (name))
-	{
-	  marker = current;
-	  current = OVL_CHAIN (current);
-	  name = DECL_NAME (OVL_FUNCTION (marker));
-	  gcc_checking_assert (name == conv_op_identifier);
-	}
 
-      if (TREE_CODE (current) == USING_DECL)
+      for (jx = ix; jx < len; jx++)
 	{
-	  current = strip_using_decl (current);
-	  if (is_overloaded_fn (current))
-	    current = NULL_TREE;
-	  else if (TREE_CODE (current) == USING_DECL)
+	  tree next = (*member_vec)[jx];
+	  if (jx != ix)
 	    {
-	      to_using = current;
-	      current = NULL_TREE;
+	      tree next_name = OVL_NAME (next);
+	      if (next_name != name)
+		{
+		  name = next_name;
+		  break;
+		}
 	    }
-	}
 
-      if (current && DECL_DECLARES_TYPE_P (current))
-	{
-	  to_type = current;
-	  current = NULL_TREE;
-	}
-
-      for (jx = ix + 1; jx < len; jx++)
-	{
-	  next = (*member_vec)[jx];
-	  next_name = OVL_NAME (next);
-	  if (next_name != name)
-	    break;
-
-	  if (marker)
+	  if (IDENTIFIER_CONV_OP_P (name))
 	    {
-	      gcc_checking_assert (OVL_FUNCTION (marker)
-				   == OVL_FUNCTION (next));
+	      marker = next;
 	      next = OVL_CHAIN (next);
 	    }
 
 	  if (TREE_CODE (next) == USING_DECL)
 	    {
+	      if (IDENTIFIER_CTOR_P (name))
+		/* Dependent inherited ctor. */
+		continue;
+
 	      next = strip_using_decl (next);
-	      if (is_overloaded_fn (next))
-		next = NULL_TREE;
-	      else if (TREE_CODE (next) == USING_DECL)
+	      if (TREE_CODE (next) == USING_DECL)
 		{
 		  to_using = next;
-		  next = NULL_TREE;
+		  continue;
 		}
+
+	      if (is_overloaded_fn (next))
+		continue;
 	    }
 
-	  if (next && DECL_DECLARES_TYPE_P (next))
-	    to_type = next;
+	  if (DECL_DECLARES_TYPE_P (next))
+	    {
+	      to_type = next;
+	      continue;
+	    }
+
+	  if (!current)
+	    current = next;
 	}
 
       if (to_using)
@@ -1671,13 +1661,15 @@  member_vec_dedup (vec<tree, va_gc> *memb
 	    current = stat_hack (current, to_type);
 	}
 
-      gcc_assert (current);
-      if (marker)
+      if (current)
 	{
-	  OVL_CHAIN (marker) = current;
-	  current = marker;
+	  if (marker)
+	    {
+	      OVL_CHAIN (marker) = current;
+	      current = marker;
+	    }
+	  (*member_vec)[store++] = current;
 	}
-      (*member_vec)[store++] = current;
     }
 
   while (store++ < len)
Index: testsuite/g++.dg/template/pr84434.C
===================================================================
--- testsuite/g++.dg/template/pr84434.C	(revision 0)
+++ testsuite/g++.dg/template/pr84434.C	(working copy)
@@ -0,0 +1,23 @@ 
+// PR c++/84434 ICE with deduction guide and dependent using decl
+// { dg-do compile { target c++17 } }
+
+template <typename T> class B {
+public:
+  template <typename U> B (U)  {}
+};
+
+template <typename T>
+struct scope_guard : B<T> {
+  using base_type = B<T>;
+
+  using base_type::base_type;
+
+   ~scope_guard() = default;
+};
+
+template <typename T>
+scope_guard (T) -> scope_guard<T>;
+
+void Frob () {
+  scope_guard (1);
+}