Patchwork PR c++/47398

login
register
mail settings
Submitter Dodji Seketeli
Date Jan. 24, 2011, 3:22 p.m.
Message ID <m3sjwil42h.fsf@redhat.com>
Download mbox | patch
Permalink /patch/80180/
State New
Headers show

Comments

Dodji Seketeli - Jan. 24, 2011, 3:22 p.m.
Hello,

In the example of the patch below, lookup_template_class resolves
transform<sizeof(TINT)> in #1 to the wrong one; it picks up the one in
#0 instead. This is because to compare the two A<a> comp_template_args
uses cp_tree_equal that fails to consider the number of siblings of
parm 'a'.

The patch makes cp_tree_equal takes the number of template parameters
in account when comparing TEMPLATE_PARM_INDEXes.

Tested on x86_64-unknown-linux-gnu against trunk.
Jason Merrill - Feb. 3, 2011, 4:59 p.m.
OK.  In future, please put the word "patch" in the subject line.

Jason
Dodji Seketeli - Feb. 3, 2011, 9:02 p.m.
Jason Merrill <jason@redhat.com> writes:

> OK.

Thanks. committed to trunk.

>  In future, please put the word "patch" in the subject line.

I will do. Sorry for the inconvenience.

Patch

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 1a1f150..d62d242 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2176,6 +2176,9 @@  cp_tree_equal (tree t1, tree t2)
 				BASELINK_FUNCTIONS (t2)));
 
     case TEMPLATE_PARM_INDEX:
+      if (TEMPLATE_PARM_NUM_SIBLINGS (t1)
+	  != TEMPLATE_PARM_NUM_SIBLINGS (t2))
+	return false;
       return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
 	      && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
 	      && (TEMPLATE_PARM_PARAMETER_PACK (t1)
diff --git a/gcc/testsuite/g++.dg/template/param1.C b/gcc/testsuite/g++.dg/template/param1.C
index ad7fc8c..a8c3791 100644
--- a/gcc/testsuite/g++.dg/template/param1.C
+++ b/gcc/testsuite/g++.dg/template/param1.C
@@ -2,11 +2,11 @@ 
 // Origin: Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 // { dg-do compile }
 
-template<int> struct A
+template<int> struct A // { dg-error "declaration" }
 {
   A();
 };
 
-template<int N, char> A<N>::A() {}  // { dg-error "got 2|but 1 required" }
+template<int N, char> A<N>::A() {}  // { dg-error "invalid use of incomplete type" }
 
 A<0> a;
diff --git a/gcc/testsuite/g++.dg/template/typedef37.C b/gcc/testsuite/g++.dg/template/typedef37.C
new file mode 100644
index 0000000..eefa383
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typedef37.C
@@ -0,0 +1,58 @@ 
+// Origin: PR c++/47398
+// { dg-do compile }
+
+template<int>
+struct A
+{
+  typedef int INT;
+};
+
+template<int I>
+struct transform
+{
+  static int bar();
+};
+
+template<class T, int a, class U, int b>
+struct B
+{
+  typedef typename A<a>::INT TINT;
+  void baz();
+};
+
+template<class T, int a, class U>
+struct B<T, a, U, 1>
+{
+  typedef typename A<a>::INT TINT;
+  void foo();
+};
+
+template<class T, int a, class U, int b>
+void
+B<T, a, U, b>::baz()
+{
+  int c = transform<sizeof(TINT)>::bar();//#0
+}
+
+template<class T, int a, class U>
+void
+B<T, a, U, 1>::foo()
+{
+  int c = transform<sizeof(TINT)>::bar();//#1
+}
+
+int
+main()
+{
+  B<int, 2, char, 1> i;
+  i.foo();
+  // While instantiating
+  //
+  //   template<class T, int a, class U> void B<T, a, U, 1>::foo()
+  //
+  // lookup_template_class resolves transform<sizeof(TINT)> in #1 to
+  // the wrong one; it picks up the one in #0 instead. This is because
+  // to compare the two A<a> comp_template_args uses cp_tree_equal
+  // that fails to consider the number of siblings of parm 'a'.
+return 0;
+}