From 70ba248488aed2c9f17d16086f3783ddd95c9244 Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Thu, 5 Jul 2012 17:24:33 -0400
Subject: [PATCH] re PR c++/53039 (including <functional> breaks
 std::is_convertible with template-pack expansion)

	PR c++/53039
	* pt.c (arg_from_parm_pack_p): Go back to using same_type_p or
	cp_tree_equal.

From-SVN: r189305
---
 gcc/cp/ChangeLog |  4 ++++
 gcc/cp/pt.c      | 35 +++++++----------------------------
 2 files changed, 11 insertions(+), 28 deletions(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f4ed6fb3ea52..4d1fc5ce27c1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
 2012-07-05  Jason Merrill  <jason@redhat.com>
 
+	PR c++/53039
+	* pt.c (arg_from_parm_pack_p): Go back to using same_type_p or
+	cp_tree_equal.
+
 	* cp-tree.h (TEMPLATE_PARM_NUM_SIBLINGS): Remove.
 	(struct template_parm_index_s): Remove num_siblings.
 	* pt.c (fixup_template_parms, fixup_template_parm_index): Remove.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e07a36242b75..df5d1f68b862 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3760,34 +3760,13 @@ arg_from_parm_pack_p (tree arg_pack, tree parm_pack)
     {
       tree expansion = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg_pack), 0);
       tree pattern = PACK_EXPANSION_PATTERN (expansion);
-      /* So we have an argument_pack<P...>.  We want to test if P
-	 is actually PARM_PACK.  We will not use cp_tree_equal to
-	 test P and PARM_PACK because during type fixup (by
-	 fixup_template_parm) P can be a pre-fixup version of a
-	 type and PARM_PACK be its post-fixup version.
-	 cp_tree_equal would consider them as different even
-	 though we would want to consider them compatible for our
-	 precise purpose here.
-
-	 Thus we are going to consider that P and PARM_PACK are
-	 compatible if they have the same DECL.  */
-      if ((/* If ARG_PACK is a type parameter pack named by the
-	      same DECL as parm_pack ...  */
-	   (TYPE_P (pattern)
-	    && TYPE_P (parm_pack)
-	    && TYPE_NAME (pattern) == TYPE_NAME (parm_pack))
-	   /* ... or if PARM_PACK is a non-type parameter named by the
-	      same DECL as ARG_PACK.  Note that PARM_PACK being a
-	      non-type parameter means it's either a PARM_DECL or a
-	      TEMPLATE_PARM_INDEX.  */
-	   || (TREE_CODE (pattern) == TEMPLATE_PARM_INDEX
-	       && ((TREE_CODE (parm_pack) == PARM_DECL
-		    && (TEMPLATE_PARM_DECL (pattern)
-			== TEMPLATE_PARM_DECL (DECL_INITIAL (parm_pack))))
-		   || (TREE_CODE (parm_pack) == TEMPLATE_PARM_INDEX
-		       && (TEMPLATE_PARM_DECL (pattern)
-			   == TEMPLATE_PARM_DECL (parm_pack))))))
-	  && template_parameter_pack_p (pattern))
+      if ((TYPE_P (pattern) && same_type_p (pattern, parm_pack))
+	  || (!TYPE_P (pattern) && cp_tree_equal (parm_pack, pattern)))
+	/* The argument pack that the parameter maps to is just an
+	   expansion of the parameter itself, such as one would
+	   find in the implicit typedef of a class inside the
+	   class itself.  Consider this parameter "unsubstituted",
+	   so that we will maintain the outer pack expansion.  */
 	return true;
     }
   return false;
-- 
GitLab