Patchwork C++ PATCH for c++/47904 (crash with template argument that uses 'this')

login
register
mail settings
Submitter Jason Merrill
Date Feb. 27, 2011, 8:13 a.m.
Message ID <4D6A078F.8050803@redhat.com>
Download mbox | patch
Permalink /patch/84680/
State New
Headers show

Comments

Jason Merrill - Feb. 27, 2011, 8:13 a.m.
When I added DECL_PARM_INDEX, it didn't occur to me that we could hit 
the code for hashing/comparing args with 'this' when used inside a 
function; I was only thinking of uses in a trailing return type, where 
'this' isn't in scope (well, wasn't...that is changing).

And while I was fixing that I also fixed the code to handle the new 
DECL_PARM_LEVEL as it should.

Tested x86_64-pc-linux-gnu, applied to trunk.  I'll backport to 4.5 soon.
commit aab5c24d944c841c308b7e86dbb86f7c17df4465
Author: Jason Merrill <jason@redhat.com>
Date:   Sat Feb 26 19:57:12 2011 -0500

    	PR c++/47904
    	* tree.c (cp_tree_equal): Compare DECL_PARM_LEVEL.
    	* pt.c (iterative_hash_template_arg): And hash it.

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index ed9d28b..4b262d0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1533,7 +1533,10 @@  iterative_hash_template_arg (tree arg, hashval_t val)
 
     case PARM_DECL:
       if (!DECL_ARTIFICIAL (arg))
-	val = iterative_hash_object (DECL_PARM_INDEX (arg), val);
+	{
+	  val = iterative_hash_object (DECL_PARM_INDEX (arg), val);
+	  val = iterative_hash_object (DECL_PARM_LEVEL (arg), val);
+	}
       return iterative_hash_template_arg (TREE_TYPE (arg), val);
 
     case TARGET_EXPR:
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d62d242..ed4f67b 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2154,12 +2154,19 @@  cp_tree_equal (tree t1, tree t2)
 
     case PARM_DECL:
       /* For comparing uses of parameters in late-specified return types
-	 with an out-of-class definition of the function.  */
-      if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
-	  && DECL_PARM_INDEX (t1) == DECL_PARM_INDEX (t2))
-	return true;
-      else
-	return false;
+	 with an out-of-class definition of the function, but can also come
+	 up for expressions that involve 'this' in a member function
+	 template.  */
+      if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+	{
+	  if (DECL_ARTIFICIAL (t1) ^ DECL_ARTIFICIAL (t2))
+	    return false;
+	  if (DECL_ARTIFICIAL (t1)
+	      || (DECL_PARM_LEVEL (t1) == DECL_PARM_LEVEL (t2)
+		  && DECL_PARM_INDEX (t1) == DECL_PARM_INDEX (t2)))
+	    return true;
+	}
+      return false;
 
     case VAR_DECL:
     case CONST_DECL:
diff --git a/gcc/testsuite/g++.dg/template/this-targ1.C b/gcc/testsuite/g++.dg/template/this-targ1.C
new file mode 100644
index 0000000..6864be5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/this-targ1.C
@@ -0,0 +1,23 @@ 
+// PR c++/47904
+
+template <bool>
+struct S
+{
+};
+
+template <class T>
+class U
+{
+  T t;
+  int foo () const
+  {
+    S <sizeof (t) == 1> s;
+    return 1;
+  }
+  int bar () const
+  {
+    S <sizeof (t) == 1> s;
+    return 1;
+  }
+};
+