mirror of git://gcc.gnu.org/git/gcc.git
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>
|
2009-11-02 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
Restrict DR 757 change to C++0x mode.
|
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;
|
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)
|
||||||
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)
|
||||||
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;
|
||||||
|
|
|
||||||
|
|
@ -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>
|
2009-11-02 Janis Johnson <janis187@us.ibm.com>
|
||||||
|
|
||||||
PR testsuite/41878
|
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