This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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
--
Nathan Sidwell
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);
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]