Commit 61e71a9e by Nathan Sidwell Committed by Nathan Sidwell

re PR c++/24386 (wrong virtual function called in template member)

cp:
	PR c++/24386
	* cp-tree.h (BASELINK_QUALIFIED_P): New.
	* pt.c (tsubst_copy_and_build): <CALL_EXPR case>: Use it.
	* typeck.c (finish_class_member_access_expr): Set it.
testsuite:
	PR c++/24386
	* g++.dg/template/overload7.C: New.

From-SVN: r105507
parent 7010f39e
2005-10-17 Nathan Sidwell <nathan@codesourcery.com> 2005-10-17 Nathan Sidwell <nathan@codesourcery.com>
PR c++/24386
* cp-tree.h (BASELINK_QUALIFIED_P): New.
* pt.c (tsubst_copy_and_build): <CALL_EXPR case>: Use it.
* typeck.c (finish_class_member_access_expr): Set it.
PR c++/21353 PR c++/21353
* decl.c (check_default_argument): Don't check * decl.c (check_default_argument): Don't check
processing_template_decl or uses_template_parms here. processing_template_decl or uses_template_parms here.
......
...@@ -52,6 +52,7 @@ struct diagnostic_context; ...@@ -52,6 +52,7 @@ struct diagnostic_context;
TYPENAME_IS_ENUM_P (in TYPENAME_TYPE) TYPENAME_IS_ENUM_P (in TYPENAME_TYPE)
REFERENCE_REF_P (in INDIRECT_EXPR) REFERENCE_REF_P (in INDIRECT_EXPR)
QUALIFIED_NAME_IS_TEMPLATE (in SCOPE_REF) QUALIFIED_NAME_IS_TEMPLATE (in SCOPE_REF)
BASELINK_QUALIFIED_P (in BASELINK)
1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE) 1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG. TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE. TEMPLATE_PARMS_FOR_INLINE.
...@@ -341,6 +342,9 @@ struct tree_overload GTY(()) ...@@ -341,6 +342,9 @@ struct tree_overload GTY(())
requested. */ requested. */
#define BASELINK_OPTYPE(NODE) \ #define BASELINK_OPTYPE(NODE) \
(TREE_CHAIN (BASELINK_CHECK (NODE))) (TREE_CHAIN (BASELINK_CHECK (NODE)))
/* Non-zero if this baselink was from a qualified lookup. */
#define BASELINK_QUALIFIED_P(NODE) \
TREE_LANG_FLAG_0 (BASELINK_CHECK (NODE))
struct tree_baselink GTY(()) struct tree_baselink GTY(())
{ {
......
...@@ -8720,9 +8720,17 @@ tsubst_copy_and_build (tree t, ...@@ -8720,9 +8720,17 @@ tsubst_copy_and_build (tree t,
} }
else else
{ {
qualified_p = (TREE_CODE (function) == COMPONENT_REF if (TREE_CODE (function) == COMPONENT_REF)
&& (TREE_CODE (TREE_OPERAND (function, 1)) {
== SCOPE_REF)); tree op = TREE_OPERAND (function, 1);
qualified_p = (TREE_CODE (op) == SCOPE_REF
|| (BASELINK_P (op)
&& BASELINK_QUALIFIED_P (op)));
}
else
qualified_p = false;
function = tsubst_copy_and_build (function, args, complain, function = tsubst_copy_and_build (function, args, complain,
in_decl, in_decl,
!qualified_p); !qualified_p);
......
...@@ -2055,10 +2055,18 @@ finish_class_member_access_expr (tree object, tree name, bool template_p) ...@@ -2055,10 +2055,18 @@ finish_class_member_access_expr (tree object, tree name, bool template_p)
expr = build_class_member_access_expr (object, member, access_path, expr = build_class_member_access_expr (object, member, access_path,
/*preserve_reference=*/false); /*preserve_reference=*/false);
if (processing_template_decl && expr != error_mark_node) if (processing_template_decl && expr != error_mark_node)
return build_min_non_dep (COMPONENT_REF, expr, {
orig_object, if (BASELINK_P (member))
BASELINK_P (member) ? member : orig_name, {
NULL_TREE); if (TREE_CODE (orig_name) == SCOPE_REF)
BASELINK_QUALIFIED_P (member) = 1;
orig_name = member;
}
return build_min_non_dep (COMPONENT_REF, expr,
orig_object, orig_name,
NULL_TREE);
}
return expr; return expr;
} }
......
2005-10-17 Nathan Sidwell <nathan@codesourcery.com> 2005-10-17 Nathan Sidwell <nathan@codesourcery.com>
PR c++/24386
* g++.dg/template/overload7.C: New.
PR c++/22551 PR c++/22551
* g++.dg/other/switch2.C: Remove expected warnings. * g++.dg/other/switch2.C: Remove expected warnings.
// { dg-do run }
// Copyright (C) 2005 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 17 Oct 2005 <nathan@codesourcery.com>
// PR 24386:Wrong virtual function called
// Origin: Scott Snyder snyder@fnal.gov
struct A
{
virtual int Foo () { return 1; }
};
struct B : public A
{
virtual int Foo () { return 2; }
};
template <class T>
int Bar (T *a)
{
if (static_cast<A*>(a)->A::Foo () != 1)
return 1;
if (static_cast<A*>(a)->Foo () != 2)
return 2;
return 0;
}
int main ()
{
return Bar (new B);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment