aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gnu.org>2009-02-03 16:26:28 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2009-02-03 16:26:28 +0000
commite350dbbd73b6e76f8c4e32307c759d978038c6dc (patch)
tree7693fb58c0b4076ed465a4e52b148bae94b43711
parentaa2bb640389ccc571935cc1c2b72ff9d1f237c41 (diff)
downloadgcc-e350dbbd73b6e76f8c4e32307c759d978038c6dc.zip
gcc-e350dbbd73b6e76f8c4e32307c759d978038c6dc.tar.gz
gcc-e350dbbd73b6e76f8c4e32307c759d978038c6dc.tar.bz2
re PR c++/36897 (ICE with function pointer template parameter)
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: r143898
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/pt.c7
-rw-r--r--gcc/cp/typeck.c14
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/template/func2.C12
-rw-r--r--gcc/testsuite/g++.dg/template/typename15.C12
-rw-r--r--gcc/testsuite/g++.dg/template/typename16.C25
7 files changed, 89 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 50fe9c2..39a5eb8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f6809f2..c5b675f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index bca72ce..1c7df31 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 254dab5..ba77486 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..b0f691d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/func2.C
@@ -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
index 0000000..fece885
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typename15.C
@@ -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
index 0000000..45da111
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typename16.C
@@ -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;
+}
+
+