public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH for c++/56247 (ICE with PMF in two template member functions)
@ 2013-02-09 20:37 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2013-02-09 20:37 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 446 bytes --]

Here, the internal representation of &Base::method in the templates 
involves an OFFSET_REF around 'this', and we were treating the two 
instances of Wrapper as equivalent.  But they involve different 'this' 
parameters, which makes a difference when we go to look up the local 
specialization.  So we need to be stricter when comparing hash table 
entries so that they aren't shared.

Tested x86_64-pc-linux-gnu, applying to trunk, 4.7 and 4.6.

[-- Attachment #2: 56247.patch --]
[-- Type: text/x-patch, Size: 3122 bytes --]

commit 504f38b8ed59af62c0226372837f8cb56765905c
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Feb 8 22:00:02 2013 -0500

    	PR c++/56247
    	* pt.c (eq_specializations): Set comparing_specializations.
    	* tree.c (cp_tree_equal): Check it.
    	* cp-tree.h: Declare it.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 303f5f6..d9270e2 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4247,6 +4247,10 @@ extern GTY(()) tree integer_two_node;
    function, two inside the body of a function in a local class, etc.)  */
 extern int function_depth;
 
+/* Nonzero if we are inside eq_specializations, which affects comparison of
+   PARM_DECLs in cp_tree_equal.  */
+extern int comparing_specializations;
+
 /* In parser.c.  */
 
 /* Nonzero if we are parsing an unevaluated operand: an operand to
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 29664ea..a3359ad 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1461,14 +1461,21 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
 /* Returns true iff two spec_entry nodes are equivalent.  Only compares the
    TMPL and ARGS members, ignores SPEC.  */
 
+int comparing_specializations;
+
 static int
 eq_specializations (const void *p1, const void *p2)
 {
   const spec_entry *e1 = (const spec_entry *)p1;
   const spec_entry *e2 = (const spec_entry *)p2;
+  int equal;
 
-  return (e1->tmpl == e2->tmpl
-	  && comp_template_args (e1->args, e2->args));
+  ++comparing_specializations;
+  equal = (e1->tmpl == e2->tmpl
+	   && comp_template_args (e1->args, e2->args));
+  --comparing_specializations;
+
+  return equal;
 }
 
 /* Returns a hash for a template TMPL and template arguments ARGS.  */
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 18d9a98..0b033c2 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2580,6 +2580,13 @@ cp_tree_equal (tree t1, tree t2)
 	 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 (comparing_specializations)
+	/* When comparing hash table entries, only an exact match is
+	   good enough; we don't want to replace 'this' with the
+	   version from another function.  */
+	return false;
+
       if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
 	{
 	  if (DECL_ARTIFICIAL (t1) ^ DECL_ARTIFICIAL (t2))
diff --git a/gcc/testsuite/g++.dg/template/ptrmem23.C b/gcc/testsuite/g++.dg/template/ptrmem23.C
new file mode 100644
index 0000000..28c0a63
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ptrmem23.C
@@ -0,0 +1,22 @@
+// PR c++/56247
+
+struct Base {
+    void method() {}
+};
+
+typedef void (Base::*MemPtr)();
+
+// Template with a member function pointer "non-type parameter".
+template<MemPtr func>
+struct Wrapper {};
+
+template<class C>
+struct Child : public Base {
+    // Templated derived class instantiates the Wrapper with the same parameter
+    // in two different virtual methods.
+    void foo() { typedef Wrapper<&Base::method> W; }
+    void bar() { typedef Wrapper<&Base::method> W; }
+};
+
+// Instantiate Child with some type.
+template class Child<int>;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2013-02-09 20:37 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-09 20:37 C++ PATCH for c++/56247 (ICE with PMF in two template member functions) Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).