diff options
author | Paolo Bonzini <bonzini@gnu.org> | 2009-02-03 16:26:28 +0000 |
---|---|---|
committer | Paolo Bonzini <bonzini@gcc.gnu.org> | 2009-02-03 16:26:28 +0000 |
commit | e350dbbd73b6e76f8c4e32307c759d978038c6dc (patch) | |
tree | 7693fb58c0b4076ed465a4e52b148bae94b43711 | |
parent | aa2bb640389ccc571935cc1c2b72ff9d1f237c41 (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/pt.c | 7 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/func2.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/typename15.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/typename16.C | 25 |
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; +} + + |