+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
{
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)))))
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;
? 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
+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.
--- /dev/null
+// 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;
+}