This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
(C++) error for converting from pointer to vbase member
- To: gcc-patches@gcc.gnu.org
- Subject: (C++) error for converting from pointer to vbase member
- From: Jason Merrill <jason@cygnus.com>
- Date: Fri, 6 Aug 1999 18:01:20 -0700
Mark's 7/26 patch broke the error for simple cases, because it was only
caught in convert_for_assignment. This patch moves the check to where it
should have been all along, and fixes the case of indirect vbases as well.
Fixes g++.other/ptrmem5.C.
1999-08-06 Jason Merrill <jason@yorick.cygnus.com>
* cvt.c (cp_convert_to_pointer): Don't force pmf conversions.
* search.c (binfo_from_vbase): New fn.
* cp-tree.h: Declare it.
* cvt.c (cp_convert_to_pointer): Use it to diagnose conversion
from pointer to member of virtual base.
* typeck.c (get_delta_difference): Likewise.
Index: search.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/search.c,v
retrieving revision 1.114
diff -c -p -r1.114 search.c
*** search.c 1999/08/04 09:07:49 1.114
--- search.c 1999/08/07 00:58:58
*************** binfo_for_vtable (var)
*** 3315,3317 ****
--- 3315,3331 ----
return dfs_walk_real (TYPE_BINFO (type),
0, dfs_bfv_helper, dfs_bfv_queue_p, &bfvi);
}
+
+ /* Returns 1 iff BINFO is from a direct or indirect virtual base. */
+
+ int
+ binfo_from_vbase (binfo)
+ tree binfo;
+ {
+ for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo))
+ {
+ if (TREE_VIA_VIRTUAL (binfo))
+ return 1;
+ }
+ return 0;
+ }
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.255
diff -c -p -r1.255 cp-tree.h
*** cp-tree.h 1999/08/04 09:07:46 1.255
--- cp-tree.h 1999/08/07 00:58:58
*************** cp-tree.h PR
*** 3343,3348 ****
--- 3343,3349 ----
extern tree current_scope PROTO((void));
extern tree lookup_conversions PROTO((tree));
extern tree binfo_for_vtable PROTO((tree));
+ extern int binfo_from_vbase PROTO((tree));
extern tree dfs_walk PROTO((tree,
tree (*)(tree, void *),
tree (*) (tree, void *),
Index: cvt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cvt.c,v
retrieving revision 1.61
diff -c -p -r1.61 cvt.c
*** cvt.c 1999/07/27 22:58:58 1.61
--- cvt.c 1999/08/07 00:58:58
***************
*** 1,5 ****
/* Language-level data type conversion for GNU C++.
! Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
--- 1,5 ----
/* Language-level data type conversion for GNU C++.
! Copyright (C) 1987-1988, 1992-1999 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
*************** cp_convert_to_pointer (type, expr)
*** 199,204 ****
--- 199,211 ----
if (binfo == error_mark_node)
return error_mark_node;
+ if (binfo_from_vbase (binfo))
+ {
+ cp_error ("conversion to `%T' from pointer to member of virtual base `%T'",
+ type, intype);
+ return error_mark_node;
+ }
+
if (TREE_CODE (expr) == PTRMEM_CST)
expr = cplus_expand_constant (expr);
*************** cp_convert_to_pointer (type, expr)
*** 217,223 ****
return rval;
}
else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
! return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 1);
else if (TYPE_PTRMEMFUNC_P (intype))
{
cp_error ("cannot convert `%E' from type `%T' to type `%T'",
--- 224,230 ----
return rval;
}
else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
! return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0);
else if (TYPE_PTRMEMFUNC_P (intype))
{
cp_error ("cannot convert `%E' from type `%T' to type `%T'",
Index: typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.183
diff -c -p -r1.183 typeck.c
*** typeck.c 1999/08/04 09:07:50 1.183
--- typeck.c 1999/08/07 00:58:58
*************** get_delta_difference (from, to, force)
*** 6213,6219 ****
binfo = get_binfo (to, from, 1);
if (binfo == 0 || binfo == error_mark_node)
return delta;
! if (TREE_VIA_VIRTUAL (binfo))
{
binfo = binfo_member (BINFO_TYPE (binfo),
CLASSTYPE_VBASECLASSES (from));
--- 6213,6219 ----
binfo = get_binfo (to, from, 1);
if (binfo == 0 || binfo == error_mark_node)
return delta;
! if (binfo_from_vbase (binfo))
{
binfo = binfo_member (BINFO_TYPE (binfo),
CLASSTYPE_VBASECLASSES (from));
*************** get_delta_difference (from, to, force)
*** 6229,6235 ****
delta);
}
! if (TREE_VIA_VIRTUAL (binfo))
{
if (force)
{
--- 6229,6235 ----
delta);
}
! if (binfo_from_vbase (binfo))
{
if (force)
{