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
This commit is contained in:
parent
dd55e286d4
commit
7eab6e7b91
|
@ -1,5 +1,13 @@
|
||||||
2005-12-22 Mark Mitchell <mark@codesourcery.com>
|
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
|
PR c++/25364
|
||||||
* typeck.c (build_unary_op): Pass DECLs not names to
|
* typeck.c (build_unary_op): Pass DECLs not names to
|
||||||
build_offset_refs.
|
build_offset_refs.
|
||||||
|
|
|
@ -3233,14 +3233,27 @@ check_default_args (tree x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark DECL as "used" in the program. If DECL is a specialization or
|
/* Mark DECL (eithet a _DECL or a BASELINK) as "used" in the program.
|
||||||
implicitly declared class member, generate the actual definition. */
|
If DECL is a specialization or implicitly declared class member,
|
||||||
|
generate the actual definition. */
|
||||||
|
|
||||||
void
|
void
|
||||||
mark_used (tree decl)
|
mark_used (tree decl)
|
||||||
{
|
{
|
||||||
HOST_WIDE_INT saved_processing_template_decl = 0;
|
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;
|
TREE_USED (decl) = 1;
|
||||||
/* If we don't need a value, then we don't need to synthesize DECL. */
|
/* If we don't need a value, then we don't need to synthesize DECL. */
|
||||||
if (skip_evaluation)
|
if (skip_evaluation)
|
||||||
|
|
38
gcc/cp/pt.c
38
gcc/cp/pt.c
|
@ -144,7 +144,6 @@ static void check_specialization_scope (void);
|
||||||
static tree process_partial_specialization (tree);
|
static tree process_partial_specialization (tree);
|
||||||
static void set_current_access_from_decl (tree);
|
static void set_current_access_from_decl (tree);
|
||||||
static void check_default_tmpl_args (tree, tree, int, int);
|
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 tree get_template_base (tree, tree, tree, tree);
|
||||||
static int verify_class_unification (tree, tree, tree);
|
static int verify_class_unification (tree, tree, tree);
|
||||||
static tree try_class_unification (tree, tree, tree, tree);
|
static tree try_class_unification (tree, tree, tree, tree);
|
||||||
|
@ -6946,39 +6945,6 @@ tsubst_exception_specification (tree fntype,
|
||||||
return new_specs;
|
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
|
/* Take the tree structure T and replace template parameters used
|
||||||
therein with the argument vector ARGS. IN_DECL is an associated
|
therein with the argument vector ARGS. IN_DECL is an associated
|
||||||
decl for diagnostics. If an error occurs, returns ERROR_MARK_NODE.
|
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. */
|
in response to the saved STMT_IS_FULL_EXPR_P setting. */
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
|
|
||||||
|
case OFFSET_REF:
|
||||||
|
mark_used (TREE_OPERAND (t, 1));
|
||||||
|
return t;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1513,12 +1513,8 @@ finish_qualified_id_expr (tree qualifying_class,
|
||||||
if (error_operand_p (expr))
|
if (error_operand_p (expr))
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
|
|
||||||
if (DECL_P (expr))
|
if (DECL_P (expr) || BASELINK_P (expr))
|
||||||
mark_used (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)
|
if (template_p)
|
||||||
check_template_keyword (expr);
|
check_template_keyword (expr);
|
||||||
|
|
|
@ -843,9 +843,9 @@ is_overloaded_fn (tree x)
|
||||||
int
|
int
|
||||||
really_overloaded_fn (tree x)
|
really_overloaded_fn (tree x)
|
||||||
{
|
{
|
||||||
/* A baselink is also considered an overloaded function. */
|
|
||||||
if (TREE_CODE (x) == OFFSET_REF)
|
if (TREE_CODE (x) == OFFSET_REF)
|
||||||
x = TREE_OPERAND (x, 1);
|
x = TREE_OPERAND (x, 1);
|
||||||
|
/* A baselink is also considered an overloaded function. */
|
||||||
if (BASELINK_P (x))
|
if (BASELINK_P (x))
|
||||||
x = BASELINK_FUNCTIONS (x);
|
x = BASELINK_FUNCTIONS (x);
|
||||||
|
|
||||||
|
|
|
@ -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>
|
2005-12-23 Paul Thomas <pault@gcc.gnu.org>
|
||||||
|
|
||||||
PR fortran/25029
|
PR fortran/25029
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue