From 6d05585b7582f089450927448e7659f62d2bdfab Mon Sep 17 00:00:00 2001 From: Mark Mitchell <mark@codesourcery.com> Date: Wed, 6 Apr 2005 05:38:34 +0000 Subject: [PATCH] re PR c++/20734 (rejects valid pointer to member) PR c++/20734 * cp-tree.def (OFFSET_REF): Correct comments. * init.c (build_offset_ref): Remove misleading comment. * typeck.c (build_unary_op): Handle pointer-to-member creation here, rather than ... (unary_complex_lvalue): ... here. PR c++/20734 * g++.dg/template/ptrmem13.C: New test. From-SVN: r97696 --- gcc/cp/cp-tree.def | 6 +- gcc/cp/init.c | 3 - gcc/cp/typeck.c | 70 ++++++++---------------- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.dg/template/ptrmem13.C | 11 ++++ 5 files changed, 42 insertions(+), 53 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/ptrmem13.C diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index 1abc77bfcad3..00f2aa1db487 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -31,10 +31,8 @@ Boston, MA 02111-1307, USA. */ BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m'). The expression is a pointer-to-member if its address is taken, - but simply denotes a member of the object if its address isnot - taken. In the latter case, resolve_offset_ref is used to - convert it to a representation of the member referred to by the - OFFSET_REF. + but simply denotes a member of the object if its address is not + taken. This form is only used during the parsing phase; once semantic analysis has taken place they are eliminated. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 69089fe82691..726309acc6a0 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1551,9 +1551,6 @@ build_offset_ref (tree type, tree name, bool address_p) return member; } - /* In member functions, the form `type::name' is no longer - equivalent to `this->type::name', at least not until - resolve_offset_ref. */ member = build2 (OFFSET_REF, TREE_TYPE (member), decl, member); PTRMEM_OK_P (member) = 1; return member; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index a3bf1c0281f7..272dc86891fc 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4026,6 +4026,29 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) arg = OVL_CURRENT (arg); break; + case OFFSET_REF: + /* Turn a reference to a non-static data member into a + pointer-to-member. */ + { + tree type; + tree t; + + if (!PTRMEM_OK_P (arg)) + return build_unary_op (code, arg, 0); + + t = TREE_OPERAND (arg, 1); + if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE) + { + error ("cannot create pointer to reference member %qD", t); + return error_mark_node; + } + + type = build_ptrmem_type (context_for_name_lookup (t), + TREE_TYPE (t)); + t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1)); + return t; + } + default: break; } @@ -4182,52 +4205,7 @@ unary_complex_lvalue (enum tree_code code, tree arg) if (TREE_CODE (TREE_TYPE (arg)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (arg)) == METHOD_TYPE || TREE_CODE (arg) == OFFSET_REF) - { - tree t; - - gcc_assert (TREE_CODE (arg) != SCOPE_REF); - - if (TREE_CODE (arg) != OFFSET_REF) - return 0; - - t = TREE_OPERAND (arg, 1); - - /* Check all this code for right semantics. */ - if (TREE_CODE (t) == FUNCTION_DECL) - { - if (DECL_DESTRUCTOR_P (t)) - error ("taking address of destructor"); - return build_unary_op (ADDR_EXPR, t, 0); - } - if (TREE_CODE (t) == VAR_DECL) - return build_unary_op (ADDR_EXPR, t, 0); - else - { - tree type; - - if (TREE_OPERAND (arg, 0) - && ! is_dummy_object (TREE_OPERAND (arg, 0)) - && TREE_CODE (t) != FIELD_DECL) - { - error ("taking address of bound pointer-to-member expression"); - return error_mark_node; - } - if (!PTRMEM_OK_P (arg)) - return build_unary_op (code, arg, 0); - - if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE) - { - error ("cannot create pointer to reference member %qD", t); - return error_mark_node; - } - - type = build_ptrmem_type (context_for_name_lookup (t), - TREE_TYPE (t)); - t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1)); - return t; - } - } - + return NULL_TREE; /* We permit compiler to make function calls returning objects of aggregate type look like lvalues. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3a61f76bc5cf..3c3678a2523f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-04-05 Mark Mitchell <mark@codesourcery.com> + + PR c++/20734 + * g++.dg/template/ptrmem13.C: New test. + 2005-04-05 Per Bothner <per@bothner.com> * lib/gcc.exp: Always add -fno-show-column, for now. diff --git a/gcc/testsuite/g++.dg/template/ptrmem13.C b/gcc/testsuite/g++.dg/template/ptrmem13.C new file mode 100644 index 000000000000..84374ea05fc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem13.C @@ -0,0 +1,11 @@ +// PR c++/20734 + +struct A; +void blah(int A::*); +struct A{ + int a; +}; +template<typename T> +void hoho(){ + blah(&A::a); +} -- GitLab