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
This commit is contained in:
Nathan Sidwell 2005-10-17 17:25:17 +00:00 committed by Nathan Sidwell
parent 7010f39ea6
commit 61e71a9e5e
6 changed files with 66 additions and 7 deletions

View File

@ -1,5 +1,10 @@
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
* decl.c (check_default_argument): Don't check
processing_template_decl or uses_template_parms here.

View File

@ -52,6 +52,7 @@ struct diagnostic_context;
TYPENAME_IS_ENUM_P (in TYPENAME_TYPE)
REFERENCE_REF_P (in INDIRECT_EXPR)
QUALIFIED_NAME_IS_TEMPLATE (in SCOPE_REF)
BASELINK_QUALIFIED_P (in BASELINK)
1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@ -341,6 +342,9 @@ struct tree_overload GTY(())
requested. */
#define BASELINK_OPTYPE(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(())
{

View File

@ -8720,9 +8720,17 @@ tsubst_copy_and_build (tree t,
}
else
{
qualified_p = (TREE_CODE (function) == COMPONENT_REF
&& (TREE_CODE (TREE_OPERAND (function, 1))
== SCOPE_REF));
if (TREE_CODE (function) == COMPONENT_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,
in_decl,
!qualified_p);

View File

@ -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,
/*preserve_reference=*/false);
if (processing_template_decl && expr != error_mark_node)
return build_min_non_dep (COMPONENT_REF, expr,
orig_object,
BASELINK_P (member) ? member : orig_name,
NULL_TREE);
{
if (BASELINK_P (member))
{
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;
}

View File

@ -1,5 +1,8 @@
2005-10-17 Nathan Sidwell <nathan@codesourcery.com>
PR c++/24386
* g++.dg/template/overload7.C: New.
PR c++/22551
* g++.dg/other/switch2.C: Remove expected warnings.

View File

@ -0,0 +1,31 @@
// { 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);
}