From 9d5874cf05b0cabd722dfbc1d5acb8c11f067fc7 Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Mon, 2 Nov 2009 19:55:02 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/pt.c | 26 ++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/other/ptrmem10.C | 29 +++++++++++++++++++++++++++ gcc/testsuite/g++.dg/other/ptrmem11.C | 21 +++++++++++++++++++ 5 files changed, 89 insertions(+) create mode 100644 gcc/testsuite/g++.dg/other/ptrmem10.C create mode 100644 gcc/testsuite/g++.dg/other/ptrmem11.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1921f7288b2..10fa16a2421 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2009-11-02 Dodji Seketeli + + 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 Restrict DR 757 change to C++0x mode. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 2f0fa125376..5af348a1390 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 ace8f7e1ba3..cfc4a0a3b80 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-11-02 Dodji Seketeli + + PR c++/37093 + * g++.dg/other/ptrmem10.C: New test. + * g++.dg/other/ptrmem11.C: Likewise. + 2009-11-02 Janis Johnson 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 00000000000..4b8c40ac8ec --- /dev/null +++ b/gcc/testsuite/g++.dg/other/ptrmem10.C @@ -0,0 +1,29 @@ +// Contributed by Dodji Seketeli +// Origin PR c++/37093 + +template +static +void foo(void *obj) +{ + C *p = static_cast(obj); + (p->*M)(); +} + +template +static void +bar(C *c, void (C::*m) ()) +{ + foo((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 00000000000..a850c55c40a --- /dev/null +++ b/gcc/testsuite/g++.dg/other/ptrmem11.C @@ -0,0 +1,21 @@ +// Contributed by Dodji Seketeli +// Origin PR c++/37093 + +struct A {}; + +template +int +foo(A* q) +{ + return q->*p; +} + +template +int +bar(int T::* p) +{ + return foo

(0);// { dg-error "(not a valid template arg|no matching func|pointer-to-member)" } +} + +int i = bar(0); + -- 2.30.2