From 7eab6e7b91cdf2dbd17595eac46173e3ce65dd84 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 23 Dec 2005 07:40:04 +0000 Subject: [PATCH] re PR c++/25369 (use of inline function in template class leads to undefined reference) PR c++/25369 * g++.dg/template/ptrmem16.C: New test. PR c++/25369 * tree.c (really_overloaded_fn): Tweak comment. * pt.c (tsubst_call_declarator_parms): Remove. (tsubst_copy): Call mark_used on the member referenced by an OFFSET_REF. * semantics.c (finish_qualified_id_expr): Simplify. * decl2.c (mark_used): Accept BASELINKs. From-SVN: r109010 --- gcc/cp/ChangeLog | 8 +++++ gcc/cp/decl2.c | 17 +++++++++-- gcc/cp/pt.c | 38 +++--------------------- gcc/cp/semantics.c | 6 +--- gcc/cp/tree.c | 2 +- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/template/ptrmem16.C | 20 +++++++++++++ 7 files changed, 54 insertions(+), 42 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/ptrmem16.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 705edbb5757..5d906193e73 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2005-12-22 Mark Mitchell + PR c++/25369 + * tree.c (really_overloaded_fn): Tweak comment. + * pt.c (tsubst_call_declarator_parms): Remove. + (tsubst_copy): Call mark_used on the member referenced by an + OFFSET_REF. + * semantics.c (finish_qualified_id_expr): Simplify. + * decl2.c (mark_used): Accept BASELINKs. + PR c++/25364 * typeck.c (build_unary_op): Pass DECLs not names to build_offset_refs. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 8c65d946a97..10296a708a1 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3233,14 +3233,27 @@ check_default_args (tree x) } } -/* Mark DECL as "used" in the program. If DECL is a specialization or - implicitly declared class member, generate the actual definition. */ +/* Mark DECL (eithet a _DECL or a BASELINK) as "used" in the program. + If DECL is a specialization or implicitly declared class member, + generate the actual definition. */ void mark_used (tree decl) { HOST_WIDE_INT saved_processing_template_decl = 0; + /* If DECL is a BASELINK for a single function, then treat it just + like the DECL for the function. Otherwise, if the BASELINK is + for an overloaded function, we don't know which function was + actually used until after overload resolution. */ + if (TREE_CODE (decl) == BASELINK) + { + decl = BASELINK_FUNCTIONS (decl); + if (really_overloaded_fn (decl)) + return; + decl = OVL_CURRENT (decl); + } + TREE_USED (decl) = 1; /* If we don't need a value, then we don't need to synthesize DECL. */ if (skip_evaluation) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9e610bf047c..93dad098689 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -144,7 +144,6 @@ static void check_specialization_scope (void); static tree process_partial_specialization (tree); static void set_current_access_from_decl (tree); static void check_default_tmpl_args (tree, tree, int, int); -static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree); static tree get_template_base (tree, tree, tree, tree); static int verify_class_unification (tree, tree, tree); static tree try_class_unification (tree, tree, tree, tree); @@ -6946,39 +6945,6 @@ tsubst_exception_specification (tree fntype, return new_specs; } -/* Substitute into the PARMS of a call-declarator. */ - -static tree -tsubst_call_declarator_parms (tree parms, - tree args, - tsubst_flags_t complain, - tree in_decl) -{ - tree new_parms; - tree type; - tree defarg; - - if (!parms || parms == void_list_node) - return parms; - - new_parms = tsubst_call_declarator_parms (TREE_CHAIN (parms), - args, complain, in_decl); - - /* Figure out the type of this parameter. */ - type = tsubst (TREE_VALUE (parms), args, complain, in_decl); - - /* Figure out the default argument as well. Note that we use - tsubst_expr since the default argument is really an expression. */ - defarg = tsubst_expr (TREE_PURPOSE (parms), args, complain, in_decl); - - /* Chain this parameter on to the front of those we have already - processed. We don't use hash_tree_cons because that function - doesn't check TREE_PARMLIST. */ - new_parms = tree_cons (defarg, type, new_parms); - - return new_parms; -} - /* Take the tree structure T and replace template parameters used therein with the argument vector ARGS. IN_DECL is an associated decl for diagnostics. If an error occurs, returns ERROR_MARK_NODE. @@ -8111,6 +8077,10 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) in response to the saved STMT_IS_FULL_EXPR_P setting. */ gcc_unreachable (); + case OFFSET_REF: + mark_used (TREE_OPERAND (t, 1)); + return t; + default: return t; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index a200bf4eae0..6912e002d8c 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1513,12 +1513,8 @@ finish_qualified_id_expr (tree qualifying_class, if (error_operand_p (expr)) return error_mark_node; - if (DECL_P (expr)) + if (DECL_P (expr) || BASELINK_P (expr)) mark_used (expr); - else if (BASELINK_P (expr) - && TREE_CODE (BASELINK_FUNCTIONS (expr)) != TEMPLATE_ID_EXPR - && !really_overloaded_fn (BASELINK_FUNCTIONS (expr))) - mark_used (OVL_CURRENT (BASELINK_FUNCTIONS (expr))); if (template_p) check_template_keyword (expr); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 4340c69e1d3..9575c49d334 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -843,9 +843,9 @@ is_overloaded_fn (tree x) int really_overloaded_fn (tree x) { - /* A baselink is also considered an overloaded function. */ if (TREE_CODE (x) == OFFSET_REF) x = TREE_OPERAND (x, 1); + /* A baselink is also considered an overloaded function. */ if (BASELINK_P (x)) x = BASELINK_FUNCTIONS (x); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c8789a0e6b..87557d863a7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-12-22 Mark Mitchell + + PR c++/25369 + * g++.dg/template/ptrmem16.C: New test. + 2005-12-23 Paul Thomas PR fortran/25029 diff --git a/gcc/testsuite/g++.dg/template/ptrmem16.C b/gcc/testsuite/g++.dg/template/ptrmem16.C new file mode 100644 index 00000000000..770581db828 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem16.C @@ -0,0 +1,20 @@ +// PR c++/25369 +// { dg-do link } + +template struct A +{ + void foo() {} +}; + +void bar(void (A::*)()) {} + +template void baz() +{ + bar(&A::foo); +} + +int main() +{ + baz<0>(); + return 0; +}