This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/47904 (crash with template argument that uses 'this')
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 27 Feb 2011 03:13:03 -0500
- Subject: C++ PATCH for c++/47904 (crash with template argument that uses 'this')
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.
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;
+ }
+};
+