aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2005-10-17 17:25:17 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2005-10-17 17:25:17 +0000
commit61e71a9e5e6c268d7c9ad25c6bec24829045de63 (patch)
tree5055e39b8fa5c9ba880cc4f3b2854285492cc5a7 /gcc
parent7010f39ea6c659080e9aaf7327585a58f4d1a666 (diff)
downloadgcc-61e71a9e5e6c268d7c9ad25c6bec24829045de63.zip
gcc-61e71a9e5e6c268d7c9ad25c6bec24829045de63.tar.gz
gcc-61e71a9e5e6c268d7c9ad25c6bec24829045de63.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/pt.c14
-rw-r--r--gcc/cp/typeck.c16
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/template/overload7.C31
6 files changed, 66 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a725969..08344ee 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9a2becc..b63d08e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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(())
{
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3de54a4..d25130a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index e3c431d..a7edfc1 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e17dc16..319812a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/g++.dg/template/overload7.C b/gcc/testsuite/g++.dg/template/overload7.C
new file mode 100644
index 0000000..28bd16c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/overload7.C
@@ -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);
+}