* 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).