diff options
author | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-11-27 10:55:32 +0000 |
---|---|---|
committer | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-11-27 10:55:32 +0000 |
commit | 045ed8f8805fe6c4cb3c4ee024739588f0ca4de3 (patch) | |
tree | a663502c969fdc01fa746da34280a67ac26c0011 /gcc/cp/cvt.c | |
parent | 2a8be21eed666c48c846ef43bb9abad29da23b31 (diff) | |
download | ppe42-gcc-045ed8f8805fe6c4cb3c4ee024739588f0ca4de3.tar.gz ppe42-gcc-045ed8f8805fe6c4cb3c4ee024739588f0ca4de3.zip |
cp:
* cp-tree.h (binfo_from_vbase): Return the virtual base's binfo.
* cvt.c (cp_convert_to_pointer): Add force parameter.
Allow conversions via virtual base if forced.
(convert_to_pointer_force): Adjust call to cp_convert_to_pointer.
(ocp_convert): Likewise.
* search.c (binfo_from_vbase): Return the virtual base's binfo.
* typeck.c (get_delta_difference): Adjust handling of virtual
bases.
testsuite:
* g++.old-deja/g++.other/ptrmem8.C: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@37791 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/cvt.c')
-rw-r--r-- | gcc/cp/cvt.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 606f854269e..fe99c8f566e 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -35,7 +35,7 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "decl.h" -static tree cp_convert_to_pointer PARAMS ((tree, tree)); +static tree cp_convert_to_pointer PARAMS ((tree, tree, int)); static tree convert_to_pointer_force PARAMS ((tree, tree)); static tree build_up_reference PARAMS ((tree, tree, int)); static void warn_ref_binding PARAMS ((tree, tree, tree)); @@ -67,11 +67,14 @@ static void warn_ref_binding PARAMS ((tree, tree, tree)); else if dealing with method pointers, delegate else convert blindly else if converting class, pass off to build_type_conversion - else try C-style pointer conversion */ + else try C-style pointer conversion. If FORCE is true then allow + conversions via virtual bases (these are permitted by reinterpret_cast, + but not static_cast). */ static tree -cp_convert_to_pointer (type, expr) +cp_convert_to_pointer (type, expr, force) tree type, expr; + int force; { register tree intype = TREE_TYPE (expr); register enum tree_code form; @@ -184,6 +187,7 @@ cp_convert_to_pointer (type, expr) tree b1; tree b2; tree binfo; + tree virt_binfo; enum tree_code code; b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type)); @@ -201,11 +205,21 @@ cp_convert_to_pointer (type, expr) if (binfo == error_mark_node) return error_mark_node; - if (binfo_from_vbase (binfo)) + virt_binfo = binfo_from_vbase (binfo); + if (virt_binfo) { - cp_error ("conversion to `%T' from pointer to member of virtual base `%T'", - type, intype); - return error_mark_node; + if (force) + cp_warning ("pointer to member cast via virtual base `%T' of `%T' will only work for objects of dynamic type `%T'", + BINFO_TYPE (virt_binfo), + BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)), + code == MINUS_EXPR ? b2 : b1); + else + { + cp_error ("pointer to member cast via virtual base `%T' of `%T'", + BINFO_TYPE (virt_binfo), + BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo))); + return error_mark_node; + } } if (TREE_CODE (expr) == PTRMEM_CST) @@ -334,7 +348,7 @@ convert_to_pointer_force (type, expr) } } - return cp_convert_to_pointer (type, expr); + return cp_convert_to_pointer (type, expr, 1); } /* We are passing something to a function which requires a reference. @@ -777,7 +791,7 @@ ocp_convert (type, expr, convtype, flags) } if (code == POINTER_TYPE || code == REFERENCE_TYPE || TYPE_PTRMEMFUNC_P (type)) - return fold (cp_convert_to_pointer (type, e)); + return fold (cp_convert_to_pointer (type, e, 0)); if (code == REAL_TYPE || code == COMPLEX_TYPE) { if (IS_AGGR_TYPE (TREE_TYPE (e))) |