Commit 13f9714b by Nathan Sidwell Committed by Nathan Sidwell

call.c (standard_conversion): Reject pointer to member conversions from…

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
parent 89f99caa
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> 2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
* method.c (do_build_copy_constructor): Preserve cv * method.c (do_build_copy_constructor): Preserve cv
......
...@@ -736,8 +736,9 @@ standard_conversion (to, from, expr) ...@@ -736,8 +736,9 @@ standard_conversion (to, from, expr)
{ {
tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from)); tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from));
tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to)); 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 && (same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (TREE_TYPE (from)), (TREE_TYPE (TREE_TYPE (from)),
TREE_TYPE (TREE_TYPE (to))))) TREE_TYPE (TREE_TYPE (to)))))
...@@ -783,11 +784,12 @@ standard_conversion (to, from, expr) ...@@ -783,11 +784,12 @@ standard_conversion (to, from, expr)
tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to)); tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn))); tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn)));
tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn))); tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn)));
tree binfo = get_binfo (fbase, tbase, 1);
if (! DERIVED_FROM_P (fbase, tbase) if (!binfo || binfo_from_vbase (binfo)
|| ! same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn)) || !same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
|| ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)), || !compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),
TREE_CHAIN (TYPE_ARG_TYPES (tofn))) TREE_CHAIN (TYPE_ARG_TYPES (tofn)))
|| CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase)) || CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase))
return 0; return 0;
......
...@@ -5095,23 +5095,18 @@ build_static_cast (type, expr) ...@@ -5095,23 +5095,18 @@ build_static_cast (type, expr)
? can_convert_arg (type, intype, expr) ? can_convert_arg (type, intype, expr)
: can_convert_arg (strip_all_pointer_quals (type), : can_convert_arg (strip_all_pointer_quals (type),
strip_all_pointer_quals (intype), expr)) strip_all_pointer_quals (intype), expr))
/* This is a standard conversion. */
ok = 1; ok = 1;
else if (TYPE_PTROB_P (type) && TYPE_PTROB_P (intype)) 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; tree binfo;
if (IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype)) if (IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype))
&& (binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 0)) && (binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 0))
&& ! TREE_VIA_VIRTUAL (binfo)) && !binfo_from_vbase (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))
ok = 1; ok = 1;
} }
else if (TREE_CODE (intype) != BOOLEAN_TYPE 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> 2000-11-30 Geoffrey Keating <geoffk@redhat.com>
* gcc.c-torture/execute/20001130-2.c: New testcase. * gcc.c-torture/execute/20001130-2.c: New testcase.
......
// 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment