diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 14fc98fbbea..789fcfb6dd6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2005-10-02 Mark Mitchell + PR c++/22621 + * parser.c (cp_parser_template_argument): Don't turn "T::f" into + "(*this).T::f". + * pt.c (convert_nontype_argument): Remove ??? comment. + PR c++/23840 * tree.c (lvalue_p1): A VA_ARG_EXPR with class type is an lvalue, when class rvalues are lvalues. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7284d4b84b8..08af6e2f49b 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -9099,11 +9099,20 @@ cp_parser_template_argument (cp_parser* parser) argument = TREE_OPERAND (argument, 0); } - if (qualifying_class) + /* If ADDRESS_P, then we use finish_qualified_id_expr so + that we get a pointer-to-member, if appropriate. + However, if ADDRESS_P is false, we don't want to turn + "T::f" into "(*this).T::f". */ + if (qualifying_class && address_p) argument = finish_qualified_id_expr (qualifying_class, argument, /*done=*/true, - address_p); + /*address_p=*/true); + else if (TREE_CODE (argument) == BASELINK) + /* We don't need the information about what class was used + to name the overloaded functions. */ + argument = BASELINK_FUNCTIONS (argument); + if (TREE_CODE (argument) == VAR_DECL) { /* A variable without external linkage might still be a diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1217580f75f..82d569ba266 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3613,9 +3613,7 @@ convert_nontype_argument (tree type, tree expr) else if (TYPE_PTRFN_P (type)) { /* If the argument is a template-id, we might not have enough - context information to decay the pointer. - ??? Why static5.C requires decay and subst1.C works fine - even without it? */ + context information to decay the pointer. */ if (!type_unknown_p (expr_type)) { expr = decay_conversion (expr); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 67105b000d1..d34c5322960 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2005-10-02 Mark Mitchell + PR c++/22621 + * g++.dg/template/overload5.C : New test. + PR c++/23840 * g++.dg/expr/stdarg1.C: New test. diff --git a/gcc/testsuite/g++.dg/template/overload5.C b/gcc/testsuite/g++.dg/template/overload5.C new file mode 100644 index 00000000000..8e520e92907 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload5.C @@ -0,0 +1,28 @@ +// PR c++/22621 + +struct foo { + typedef int (*fun)(int); + + static int f(int); // overload between static & non-static + int f(); + + static int g(int); // non-overloaded static +}; + +template +struct f_obj { + // something .. +}; + +f_obj<&foo::f> a; // OK +f_obj b; // OK (note: a and b are of the same type) + +int foo::f() +{ + f_obj<&foo::f> a; // OK + f_obj b; // ERROR: foo::f cannot be a constant expression + + f_obj<&foo::g> c; // OK + f_obj d; // OK +} +