OSDN Git Service

gcc/cp:
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Feb 2009 16:26:28 +0000 (16:26 +0000)
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Feb 2009 16:26:28 +0000 (16:26 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@143898 138bc75d-0d04-0410-961f-82ee72b054a4

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 50fe9c2..39a5eb8 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 f6809f2..c5b675f 100644 (file)
@@ -4566,6 +4566,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 bca72ce..1c7df31 100644 (file)
@@ -637,6 +637,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 254dab5..ba77486 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-03  Janis Johnson  <janis187@us.ibm.com>
            Ben Elliston  <bje@au.ibm.com>
 
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;
+}
+
+