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>
Restrict DR 757 change to C++0x mode.
......
......@@ -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;
......
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
......
// 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