Commit 9d5874cf by Dodji Seketeli Committed by Dodji Seketeli

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
parent 5815841f
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> 2009-11-02 Jason Merrill <jason@redhat.com>
Restrict DR 757 change to C++0x mode. Restrict DR 757 change to C++0x mode.
......
...@@ -4686,6 +4686,22 @@ convert_nontype_argument_function (tree type, tree expr) ...@@ -4686,6 +4686,22 @@ convert_nontype_argument_function (tree type, tree expr)
return fn; 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 /* Attempt to convert the non-type template parameter EXPR to the
indicated TYPE. If the conversion is successful, return the indicated TYPE. If the conversion is successful, return the
converted value. If the conversion is unsuccessful, return converted value. If the conversion is unsuccessful, return
...@@ -4985,6 +5001,11 @@ convert_nontype_argument (tree type, tree expr) ...@@ -4985,6 +5001,11 @@ convert_nontype_argument (tree type, tree expr)
if (expr == error_mark_node) if (expr == error_mark_node)
return 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 /* There is no way to disable standard conversions in
resolve_address_of_overloaded_function (called by resolve_address_of_overloaded_function (called by
instantiate_type). It is possible that the call succeeded by instantiate_type). It is possible that the call succeeded by
...@@ -5011,6 +5032,11 @@ convert_nontype_argument (tree type, tree expr) ...@@ -5011,6 +5032,11 @@ convert_nontype_argument (tree type, tree expr)
qualification conversions (_conv.qual_) are applied. */ qualification conversions (_conv.qual_) are applied. */
else if (TYPE_PTRMEM_P (type)) 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); expr = perform_qualification_conversions (type, expr);
if (expr == error_mark_node) if (expr == error_mark_node)
return expr; return expr;
......
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> 2009-11-02 Janis Johnson <janis187@us.ibm.com>
PR testsuite/41878 PR testsuite/41878
......
// 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);
}
// 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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment