From 627bc9388801cc03a5c377850870e9e94432db29 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 6 Jul 2010 15:22:49 -0400 Subject: [PATCH] re PR c++/44778 (? Behaviour change with pointers to members) PR c++/44778 * init.c (build_offset_ref): If scope isn't dependent, don't exit early. Look at TYPE_MAIN_VARIANT. * pt.c (tsubst_copy) [OFFSET_REF]: Do substitution. From-SVN: r161879 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/init.c | 14 +++----------- gcc/cp/pt.c | 9 +++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/template/ptrmem17.C | 2 +- gcc/testsuite/g++.dg/template/ptrmem22.C | 29 +++++++++++++++++++++++++++++ 6 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/ptrmem22.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index eb7a5ba..499bd0d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2010-07-06 Jason Merrill + PR c++/44778 + * init.c (build_offset_ref): If scope isn't dependent, + don't exit early. Look at TYPE_MAIN_VARIANT. + * pt.c (tsubst_copy) [OFFSET_REF]: Do substitution. + * error.c (dump_function_decl): Don't crash on null DECL_NAME. 2010-07-06 Shujing Zhao diff --git a/gcc/cp/init.c b/gcc/cp/init.c index ec7dca9..20f921d 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1507,18 +1507,9 @@ build_offset_ref (tree type, tree member, bool address_p) if (TREE_CODE (member) == TEMPLATE_DECL) return member; - if (dependent_type_p (type) || type_dependent_expression_p (member)) - { - tree ref, mem_type = NULL_TREE; - if (!dependent_scope_p (type)) - mem_type = TREE_TYPE (member); - ref = build_qualified_name (mem_type, type, member, + if (dependent_scope_p (type) || type_dependent_expression_p (member)) + return build_qualified_name (NULL_TREE, type, member, /*template_p=*/false); - /* Undo convert_from_reference. */ - if (TREE_CODE (ref) == INDIRECT_REF) - ref = TREE_OPERAND (ref, 0); - return ref; - } gcc_assert (TYPE_P (type)); if (! is_class_type (type, 1)) @@ -1528,6 +1519,7 @@ build_offset_ref (tree type, tree member, bool address_p) /* Callers should call mark_used before this point. */ gcc_assert (!DECL_P (member) || TREE_USED (member)); + type = TYPE_MAIN_VARIANT (type); if (!COMPLETE_OR_OPEN_TYPE_P (complete_type (type))) { error ("incomplete type %qT does not have member %qD", type, member); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f542b21..80cf7d2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11309,8 +11309,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) gcc_unreachable (); case OFFSET_REF: - mark_used (TREE_OPERAND (t, 1)); - return t; + r = build2 + (code, tsubst (TREE_TYPE (t), args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), + tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl)); + PTRMEM_OK_P (r) = PTRMEM_OK_P (t); + mark_used (TREE_OPERAND (r, 1)); + return r; case EXPR_PACK_EXPANSION: error ("invalid use of pack expansion expression"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cf61679..b840179 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-07-06 Jason Merrill + + PR c++/44778 + * g++.dg/template/ptrmem22.C: New. + 2010-07-06 Kai Tietz * gcc.target/i386/ms_hook_prologue.c: Add x64 ms_hook_prologue diff --git a/gcc/testsuite/g++.dg/template/ptrmem17.C b/gcc/testsuite/g++.dg/template/ptrmem17.C index a79e3c8..5c5ee3f 100644 --- a/gcc/testsuite/g++.dg/template/ptrmem17.C +++ b/gcc/testsuite/g++.dg/template/ptrmem17.C @@ -7,4 +7,4 @@ template struct A ~A() { &A::i; } // { dg-error "reference" } }; -A<0> a; // { dg-message "instantiated" } +A<0> a; diff --git a/gcc/testsuite/g++.dg/template/ptrmem22.C b/gcc/testsuite/g++.dg/template/ptrmem22.C new file mode 100644 index 0000000..762f377 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem22.C @@ -0,0 +1,29 @@ +// PR c++/44778 + +enum Healpix_Ordering_Scheme { RING, NEST }; + +class Healpix_Base + { + protected: + Healpix_Ordering_Scheme scheme_; + int nest2ring (int pix) const; + int ring2nest (int pix) const; + + typedef int (Healpix_Base::*swapfunc)(int pix) const; + }; + +template class Healpix_Map: public Healpix_Base + { + public: + void Import_nograde (const Healpix_Map &orig) + { + swapfunc swapper = (scheme_ == NEST) ? + &Healpix_Map::ring2nest : &Healpix_Map::nest2ring; + } + }; + +int main() + { + Healpix_Map a,b; + a.Import_nograde(b); + } -- 2.7.4