aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-12-23 07:40:04 +0000
committerMark Mitchell <mark@codesourcery.com>2005-12-23 07:40:04 +0000
commitc8644731402a98a5f6489cbc301146b7888bb2a3 (patch)
treed3c9d42deb43cc0a2a85375a47e5680b0096e26c
parent5f57e7406c52ada072358dbf38e434ce43c93c5e (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@109010 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/decl2.c17
-rw-r--r--gcc/cp/pt.c38
-rw-r--r--gcc/cp/semantics.c6
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/ptrmem16.C20
7 files changed, 54 insertions, 42 deletions
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 <mark@codesourcery.com>
+ 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 <mark@codesourcery.com>
+
+ PR c++/25369
+ * g++.dg/template/ptrmem16.C: New test.
+
2005-12-23 Paul Thomas <pault@gcc.gnu.org>
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 <typename> struct A
+{
+ void foo() {}
+};
+
+void bar(void (A<int>::*)()) {}
+
+template <int> void baz()
+{
+ bar(&A<int>::foo);
+}
+
+int main()
+{
+ baz<0>();
+ return 0;
+}