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
This commit is contained in:
parent
5815841f11
commit
9d5874cf05
|
@ -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.
|
||||
|
|
26
gcc/cp/pt.c
26
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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
Loading…
Reference in New Issue