diff options
author | Dodji Seketeli <dodji@redhat.com> | 2009-11-02 19:55:02 +0000 |
---|---|---|
committer | Dodji Seketeli <dodji@gcc.gnu.org> | 2009-11-02 20:55:02 +0100 |
commit | 9d5874cf05b0cabd722dfbc1d5acb8c11f067fc7 (patch) | |
tree | 3a220827c8faa9f288db192ce601a0e0bc67433a | |
parent | 5815841f113b625c746a17e3ddf0deb1458e9d40 (diff) | |
download | gcc-9d5874cf05b0cabd722dfbc1d5acb8c11f067fc7.zip gcc-9d5874cf05b0cabd722dfbc1d5acb8c11f067fc7.tar.gz gcc-9d5874cf05b0cabd722dfbc1d5acb8c11f067fc7.tar.bz2 |
re PR c++/37093 (ICE with pointer to member template parameters)
Fix PR c++/37093
gcc/cp/ChangeLog:
PR c++/37093
* pt.c (check_valid_ptrmem_cst_expr): New function.
(convert_nontype_argument): Use it to output an error for
illegal pointer to member expressions used as template arguments.
gcc/testsuite/ChangeLog:
PR c++/37093
* g++.dg/other/ptrmem10.C: New test.
* g++.dg/other/ptrmem11.C: Likewise.
From-SVN: r153822
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/pt.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/ptrmem10.C | 29 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/ptrmem11.C | 21 |
5 files changed, 89 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1921f72..10fa16a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2009-11-02 Dodji Seketeli <dodji@redhat.com> + + PR c++/37093 + * pt.c (check_valid_ptrmem_cst_expr): New function. + (convert_nontype_argument): Use it to output an error for + illegal pointer to member expressions used as template arguments. + 2009-11-02 Jason Merrill <jason@redhat.com> Restrict DR 757 change to C++0x mode. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 2f0fa12..5af348a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4686,6 +4686,22 @@ convert_nontype_argument_function (tree type, tree expr) return fn; } +/* Subroutine of convert_nontype_argument. + Check if EXPR of type TYPE is a valid pointer-to-member constant. + Emit an error otherwise. */ + +static bool +check_valid_ptrmem_cst_expr (tree type, tree expr) +{ + STRIP_NOPS (expr); + if (expr && (null_ptr_cst_p (expr) || TREE_CODE (expr) == PTRMEM_CST)) + return true; + error ("%qE is not a valid template argument for type %qT", + expr, type); + error ("it must be a pointer-to-member of the form `&X::Y'"); + return false; +} + /* Attempt to convert the non-type template parameter EXPR to the indicated TYPE. If the conversion is successful, return the converted value. If the conversion is unsuccessful, return @@ -4985,6 +5001,11 @@ convert_nontype_argument (tree type, tree expr) if (expr == error_mark_node) return error_mark_node; + /* [temp.arg.nontype] bullet 1 says the pointer to member + expression must be a pointer-to-member constant. */ + if (!check_valid_ptrmem_cst_expr (type, expr)) + return error_mark_node; + /* There is no way to disable standard conversions in resolve_address_of_overloaded_function (called by instantiate_type). It is possible that the call succeeded by @@ -5011,6 +5032,11 @@ convert_nontype_argument (tree type, tree expr) qualification conversions (_conv.qual_) are applied. */ else if (TYPE_PTRMEM_P (type)) { + /* [temp.arg.nontype] bullet 1 says the pointer to member + expression must be a pointer-to-member constant. */ + if (!check_valid_ptrmem_cst_expr (type, expr)) + return error_mark_node; + expr = perform_qualification_conversions (type, expr); if (expr == error_mark_node) return expr; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ace8f7e..cfc4a0a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-11-02 Dodji Seketeli <dodji@redhat.com> + + PR c++/37093 + * g++.dg/other/ptrmem10.C: New test. + * g++.dg/other/ptrmem11.C: Likewise. + 2009-11-02 Janis Johnson <janis187@us.ibm.com> PR testsuite/41878 diff --git a/gcc/testsuite/g++.dg/other/ptrmem10.C b/gcc/testsuite/g++.dg/other/ptrmem10.C new file mode 100644 index 0000000..4b8c40a --- /dev/null +++ b/gcc/testsuite/g++.dg/other/ptrmem10.C @@ -0,0 +1,29 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/37093 + +template <class C, void (C::*M) ()> +static +void foo(void *obj) +{ + C *p = static_cast<C*>(obj); + (p->*M)(); +} + +template <class C> +static void +bar(C *c, void (C::*m) ()) +{ + foo<C,m>((void *)c);// { dg-error "(not a valid template arg|pointer-to-member|no matching fun)" } +} + +struct S +{ + void baz () {} +}; + +int +main () +{ + S a; + bar(&a, &S::baz); +} diff --git a/gcc/testsuite/g++.dg/other/ptrmem11.C b/gcc/testsuite/g++.dg/other/ptrmem11.C new file mode 100644 index 0000000..a850c55 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/ptrmem11.C @@ -0,0 +1,21 @@ +// Contributed by Dodji Seketeli <dodji@redhat.com> +// Origin PR c++/37093 + +struct A {}; + +template <int A::* p> +int +foo(A* q) +{ + return q->*p; +} + +template <typename T> +int +bar(int T::* p) +{ + return foo<p>(0);// { dg-error "(not a valid template arg|no matching func|pointer-to-member)" } +} + +int i = bar<A>(0); + |