]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/36897 (ICE with function pointer template parameter)
authorPaolo Bonzini <bonzini@gnu.org>
Tue, 3 Feb 2009 15:56:05 +0000 (15:56 +0000)
committerPaolo Bonzini <bonzini@gcc.gnu.org>
Tue, 3 Feb 2009 15:56:05 +0000 (15:56 +0000)
gcc/cp:
2009-02-03  Paolo Bonzini  <bonzini@gnu.org>

PR c++/36897
* pt.c (convert_nontype_argument_function): Expect expr to be an
ADDR_EXPR.

PR c++/37314
* typeck.c (merge_types): Call resolve_typename_type if only
one type is a typename.

gcc/testsuite:
2009-02-03  Paolo Bonzini  <bonzini@gnu.org>

PR c++/36897
* g++.dg/template/func2.C: New test.

PR c++/37314
* g++.dg/template/typename15.C: New.
* g++.dg/template/typename16.C: New.

From-SVN: r143896

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/func2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/typename15.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/typename16.C [new file with mode: 0644]

index ee9a08fb996c2bcc49ecfae9037d9ee6e3475f3a..f19a0fde93d74fd9dcfb92ca92b07d502e9721fc 100644 (file)
@@ -1,3 +1,13 @@
+2009-02-03  Paolo Bonzini  <bonzini@gnu.org>
+
+       PR c++/36897
+       * pt.c (convert_nontype_argument_function): Expect expr to be an
+       ADDR_EXPR.
+
+       PR c++/37314
+       * typeck.c (merge_types): Call resolve_typename_type if only
+       one type is a typename.
+
 2009-02-02  Jason Merrill  <jason@redhat.com>
 
        PR c++/39054
index 54e2f7da496a6ec5648cbe52498ee4d9d21d5d1f..7f4a5a2cfdc80ff16416f4a689ccdf69cb0296c4 100644 (file)
@@ -4555,6 +4555,13 @@ convert_nontype_argument (tree type, tree expr)
       expr = convert_nontype_argument_function (type, expr);
       if (!expr || expr == error_mark_node)
        return expr;
+
+      if (TREE_CODE (expr) != ADDR_EXPR)
+       {
+         error ("%qE is not a valid template argument for type %qT", expr, type);
+         error ("it must be the address of a function with external linkage");
+         return NULL_TREE;
+       }
     }
   /* [temp.arg.nontype]/5, bullet 5
 
index cf77e7a304e93aeca42902fc6b134e3b99c4dd1f..e8094b746845fa3ef18eda69239a4ff551bac1f7 100644 (file)
@@ -608,6 +608,20 @@ merge_types (tree t1, tree t2)
 
   code1 = TREE_CODE (t1);
   code2 = TREE_CODE (t2);
+  if (code1 != code2)
+    {
+      gcc_assert (code1 == TYPENAME_TYPE || code2 == TYPENAME_TYPE);
+      if (code1 == TYPENAME_TYPE)
+       {
+          t1 = resolve_typename_type (t1, /*only_current_p=*/true);
+         code1 = TREE_CODE (t1);
+       }
+      else
+       {
+          t2 = resolve_typename_type (t2, /*only_current_p=*/true);
+         code2 = TREE_CODE (t2);
+       }
+    }
 
   switch (code1)
     {
index 54e2db01b5ca4104f861192362c4d5e861b98059..9aef984fa9be9b3bed029142faba924a4237b20d 100644 (file)
@@ -1,3 +1,12 @@
+2009-02-03  Paolo Bonzini  <bonzini@gnu.org>
+
+       PR c++/36897
+       * g++.dg/template/func2.C: New test.
+
+       PR c++/37314
+       * g++.dg/template/typename15.C: New.
+       * g++.dg/template/typename16.C: New.
+
 2009-02-02  Jason Merrill  <jason@redhat.com>
 
        PR c++/39054
diff --git a/gcc/testsuite/g++.dg/template/func2.C b/gcc/testsuite/g++.dg/template/func2.C
new file mode 100644 (file)
index 0000000..b0f691d
--- /dev/null
@@ -0,0 +1,12 @@
+// { dg-do compile }
+
+typedef void (*fptr)();
+fptr zeroptr = 0;
+template<typename T, fptr F> struct foo { };
+template<typename T> struct foo<T,zeroptr> { };
+// { dg-error "not a valid template argument" "not valid" { target *-*-* } 6 } 
+// { dg-error "must be the address" "must be the address " { target *-*-* } 6 }
+
+// The rest is needed to trigger the ICE in 4.0 to 4.3:
+void f() { }
+foo<int,&f> m_foo;
diff --git a/gcc/testsuite/g++.dg/template/typename15.C b/gcc/testsuite/g++.dg/template/typename15.C
new file mode 100644 (file)
index 0000000..fece885
--- /dev/null
@@ -0,0 +1,12 @@
+// PR37314 ice-on-valid-code, from w.doeringer
+template <typename T>
+class Cdeque {
+    typedef T *pointer;
+    class iterator {
+        typedef typename Cdeque<T>::pointer pointer;
+        pointer operator->();
+    };
+};
+template <typename T> T* Cdeque<T>::iterator::operator->() { }
+
+
diff --git a/gcc/testsuite/g++.dg/template/typename16.C b/gcc/testsuite/g++.dg/template/typename16.C
new file mode 100644 (file)
index 0000000..45da111
--- /dev/null
@@ -0,0 +1,25 @@
+// PR37314 rejects-valid, from w.doeringer
+template <typename T>
+struct A {
+  typedef __PTRDIFF_TYPE__ difference_type;
+  struct B {
+    typedef typename A<T>::difference_type difference_type;
+    difference_type operator-(B const&) const; 
+    T t;
+  };
+};
+// 
+
+template <typename T>
+typename A<T>::B::difference_type A<T>::B::operator-(B const&) const {
+  return -1;
+} 
+
+//
+int main() {
+  A<int>::B i;
+  ++i.t;
+  return 0;
+}
+
+