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
This commit is contained in:
parent
89f99caaab
commit
13f9714bb6
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
57
gcc/testsuite/g++.old-deja/g++.other/cast6.C
Normal file
57
gcc/testsuite/g++.old-deja/g++.other/cast6.C
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user