aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2000-12-01 11:52:33 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2000-12-01 11:52:33 +0000
commit13f9714bb6a00a628ed654f3863cb7ed7b7d9eee (patch)
treef80d9f0fedea5248099a5177e8a9fea9a12d0a08 /gcc
parent89f99caaab615ca3e4566a5fe4db97a88fb1e0f4 (diff)
downloadgcc-13f9714bb6a00a628ed654f3863cb7ed7b7d9eee.zip
gcc-13f9714bb6a00a628ed654f3863cb7ed7b7d9eee.tar.gz
gcc-13f9714bb6a00a628ed654f3863cb7ed7b7d9eee.tar.bz2
call.c (standard_conversion): Reject pointer to member conversions from ambiguous, inaccessible or virtual bases.
cp: * call.c (standard_conversion): Reject pointer to member conversions from ambiguous, inaccessible or virtual bases. * typeck.c (build_static_cast): Don't check pointers to members specially. testsuite: * g++.old-deja/g++.other/cast6.C: New test. From-SVN: r37914
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/call.c12
-rw-r--r--gcc/cp/typeck.c17
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/cast6.C57
5 files changed, 81 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8c3934f..8654377 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2000-12-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (standard_conversion): Reject pointer to member
+ conversions from ambiguous, inaccessible or virtual bases.
+ * typeck.c (build_static_cast): Don't check pointers to members
+ specially.
+
2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
* method.c (do_build_copy_constructor): Preserve cv
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index ecd3d22..fd5f904 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -736,8 +736,9 @@ standard_conversion (to, from, expr)
{
tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from));
tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to));
+ tree binfo = get_binfo (fbase, tbase, 1);
- if (DERIVED_FROM_P (fbase, tbase)
+ if (binfo && !binfo_from_vbase (binfo)
&& (same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (TREE_TYPE (from)),
TREE_TYPE (TREE_TYPE (to)))))
@@ -783,11 +784,12 @@ standard_conversion (to, from, expr)
tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn)));
tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn)));
+ tree binfo = get_binfo (fbase, tbase, 1);
- if (! DERIVED_FROM_P (fbase, tbase)
- || ! same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
- || ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),
- TREE_CHAIN (TYPE_ARG_TYPES (tofn)))
+ if (!binfo || binfo_from_vbase (binfo)
+ || !same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
+ || !compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),
+ TREE_CHAIN (TYPE_ARG_TYPES (tofn)))
|| CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase))
return 0;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 39f8b54..6f99a5f 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5095,23 +5095,18 @@ build_static_cast (type, expr)
? can_convert_arg (type, intype, expr)
: can_convert_arg (strip_all_pointer_quals (type),
strip_all_pointer_quals (intype), expr))
+ /* This is a standard conversion. */
ok = 1;
else if (TYPE_PTROB_P (type) && TYPE_PTROB_P (intype))
{
+ /* They're pointers to objects. They must be aggregates that
+ are related non-virtually. */
+
tree binfo;
+
if (IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype))
&& (binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 0))
- && ! TREE_VIA_VIRTUAL (binfo))
- ok = 1;
- }
- else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
- {
- if (same_type_ignoring_top_level_qualifiers_p
- (TREE_TYPE (TREE_TYPE (type)),
- TREE_TYPE (TREE_TYPE (intype)))
- && (binfo = get_binfo (TYPE_OFFSET_BASETYPE (TREE_TYPE (type)),
- TYPE_OFFSET_BASETYPE (TREE_TYPE (intype)), 0))
- && ! TREE_VIA_VIRTUAL (binfo))
+ && !binfo_from_vbase (binfo))
ok = 1;
}
else if (TREE_CODE (intype) != BOOLEAN_TYPE
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3363678..aae082d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2000-12-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * g++.old-deja/g++.other/cast6.C: New test.
+
2000-11-30 Geoffrey Keating <geoffk@redhat.com>
* gcc.c-torture/execute/20001130-2.c: New testcase.
diff --git a/gcc/testsuite/g++.old-deja/g++.other/cast6.C b/gcc/testsuite/g++.old-deja/g++.other/cast6.C
new file mode 100644
index 0000000..23f63e7
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/cast6.C
@@ -0,0 +1,57 @@
+// Build don't link:
+
+// Copyright (C) 2000 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 28 Nov 2000 <nathan@codesourcery.com>
+
+// We failed to reject static_cast and implicit conversions of pointers to
+// member that traversed a virtual base.
+
+struct bar
+{
+ int barm;
+ static void a();
+};
+struct filler1 {int fm;};
+struct filler2 {int fm;};
+struct filler3 {int fm;};
+struct filler4 {int fm;};
+
+struct baz : filler1, bar, filler2
+{
+ int bazm;
+};
+
+struct foo : filler3, virtual baz, filler4
+{
+ static void a();
+ void b() {};
+ int m;
+};
+
+typedef void (bar::*barfPtr)();
+typedef void (foo::*foofPtr)();
+typedef int bar::*barmPtr;
+typedef int foo::*foomPtr;
+
+struct X;
+typedef void (X::*xfPtr) ();
+typedef int X::*xmPtr;
+
+int main ()
+{
+ {
+ foofPtr fp = &foo::b;
+ barfPtr bp = static_cast <barfPtr> (fp); // ERROR - invalid static_cast
+ foofPtr fp2 = static_cast <foofPtr> (bp); // ERROR - invalid static_cast
+ foofPtr fp3 = bp; // ERROR - cannot convert
+ fp3 = (foofPtr)bp; // WARNING - via virtual base
+
+ foomPtr fmp = &foo::m;
+ barmPtr bmp = static_cast <barmPtr> (fmp); // ERROR - invalid static_cast
+ foomPtr fmp2 = static_cast <foomPtr> (bmp); // ERROR - invalid static_cast
+ foomPtr fmp3 = bmp; // ERROR - cannot convert
+ fmp3 = (foomPtr)bmp; // WARNING - via virtual base
+ }
+
+ return 0;
+}