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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@105507
138bc75d-0d04-0410-961f-
82ee72b054a4
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.
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.
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(())
{
}
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);
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;
}
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.
--- /dev/null
+// { 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);
+}