diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2000-12-01 11:52:33 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2000-12-01 11:52:33 +0000 |
commit | 13f9714bb6a00a628ed654f3863cb7ed7b7d9eee (patch) | |
tree | f80d9f0fedea5248099a5177e8a9fea9a12d0a08 /gcc | |
parent | 89f99caaab615ca3e4566a5fe4db97a88fb1e0f4 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/call.c | 12 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/cast6.C | 57 |
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; +} |