This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 11345
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 6 Jul 2003 15:22:49 -0700
- Subject: C++ PATCH: PR 11345
- Reply-to: mark at codesourcery dot com
This patch fixes PR 11345. Tested on i686-pc-linux-gnu, applied on
the mainline and on the branch. The key change is the
maybe_dummy_object bit -- we must not try to do bogus conversions.
The access8.C change makes the branch test more like the mainline
test, and was not applied on the mainline.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2003-07-06 Mark Mitchell <mark@codesourcery.com>
PR c++/11345
* search.c (lookup_base_r): Remove is_non_public and
within_current_scope parameters. Remove other dead code.
(lookup_base): Adjust call to lookup_base_r.
(adjust_result_of_qualified_name_lookup): Improve comment.
* semantics.c (finish_call_expr): Use maybe_dummy_object.
2003-07-06 Mark Mitchell <mark@codesourcery.com>
PR c++/11345
* g++.old-deja/g++.jason/access8.C: New test.
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.243.2.11
diff -c -5 -p -r1.243.2.11 search.c
*** cp/search.c 26 Jun 2003 01:05:39 -0000 1.243.2.11
--- cp/search.c 6 Jul 2003 21:53:34 -0000
*************** struct vbase_info
*** 83,93 ****
static int is_subobject_of_p PARAMS ((tree, tree, tree));
static int is_subobject_of_p_1 PARAMS ((tree, tree, tree));
static tree dfs_check_overlap PARAMS ((tree, void *));
static tree dfs_no_overlap_yet PARAMS ((tree, void *));
static base_kind lookup_base_r
! PARAMS ((tree, tree, base_access, int, int, int, tree *));
static int dynamic_cast_base_recurse PARAMS ((tree, tree, int, tree *));
static tree marked_pushdecls_p PARAMS ((tree, void *));
static tree unmarked_pushdecls_p PARAMS ((tree, void *));
static tree dfs_debug_unmarkedp PARAMS ((tree, void *));
static tree dfs_debug_mark PARAMS ((tree, void *));
--- 83,93 ----
static int is_subobject_of_p PARAMS ((tree, tree, tree));
static int is_subobject_of_p_1 PARAMS ((tree, tree, tree));
static tree dfs_check_overlap PARAMS ((tree, void *));
static tree dfs_no_overlap_yet PARAMS ((tree, void *));
static base_kind lookup_base_r
! PARAMS ((tree, tree, base_access, int, tree *));
static int dynamic_cast_base_recurse PARAMS ((tree, tree, int, tree *));
static tree marked_pushdecls_p PARAMS ((tree, void *));
static tree unmarked_pushdecls_p PARAMS ((tree, void *));
static tree dfs_debug_unmarkedp PARAMS ((tree, void *));
static tree dfs_debug_mark PARAMS ((tree, void *));
*************** static int n_contexts_saved;
*** 162,208 ****
#endif /* GATHER_STATISTICS */
/* Worker for lookup_base. BINFO is the binfo we are searching at,
BASE is the RECORD_TYPE we are searching for. ACCESS is the
! required access checks. WITHIN_CURRENT_SCOPE, IS_NON_PUBLIC and
! IS_VIRTUAL indicate how BINFO was reached from the start of the
! search. WITHIN_CURRENT_SCOPE is true if we met the current scope,
! or friend thereof (this allows us to determine whether a protected
! base is accessible or not). IS_NON_PUBLIC indicates whether BINFO
! is accessible and IS_VIRTUAL indicates if it is morally virtual.
If BINFO is of the required type, then *BINFO_PTR is examined to
compare with any other instance of BASE we might have already
discovered. *BINFO_PTR is initialized and a base_kind return value
indicates what kind of base was located.
Otherwise BINFO's bases are searched. */
static base_kind
! lookup_base_r (binfo, base, access, within_current_scope,
! is_non_public, is_virtual, binfo_ptr)
tree binfo, base;
base_access access;
- int within_current_scope;
- int is_non_public; /* inside a non-public part */
int is_virtual; /* inside a virtual part */
tree *binfo_ptr;
{
int i;
tree bases;
base_kind found = bk_not_base;
- if (access == ba_check
- && !within_current_scope
- && is_friend (BINFO_TYPE (binfo), current_scope ()))
- {
- /* Do not clear is_non_public here. If A is a private base of B, A
- is not allowed to convert a B* to an A*. */
- within_current_scope = 1;
- }
-
if (same_type_p (BINFO_TYPE (binfo), base))
{
/* We have found a base. Check against what we have found
already. */
found = bk_same_type;
--- 162,192 ----
#endif /* GATHER_STATISTICS */
/* Worker for lookup_base. BINFO is the binfo we are searching at,
BASE is the RECORD_TYPE we are searching for. ACCESS is the
! required access checks. IS_VIRTUAL indicates if BINFO is morally
! virtual.
If BINFO is of the required type, then *BINFO_PTR is examined to
compare with any other instance of BASE we might have already
discovered. *BINFO_PTR is initialized and a base_kind return value
indicates what kind of base was located.
Otherwise BINFO's bases are searched. */
static base_kind
! lookup_base_r (binfo, base, access, is_virtual, binfo_ptr)
tree binfo, base;
base_access access;
int is_virtual; /* inside a virtual part */
tree *binfo_ptr;
{
int i;
tree bases;
base_kind found = bk_not_base;
if (same_type_p (BINFO_TYPE (binfo), base))
{
/* We have found a base. Check against what we have found
already. */
found = bk_same_type;
*************** lookup_base_r (binfo, base, access, with
*** 230,280 ****
return bk_not_base;
for (i = TREE_VEC_LENGTH (bases); i--;)
{
tree base_binfo = TREE_VEC_ELT (bases, i);
- int this_non_public = is_non_public;
- int this_virtual = is_virtual;
base_kind bk;
- if (access <= ba_ignore)
- ; /* no change */
- else if (TREE_VIA_PUBLIC (base_binfo))
- ; /* no change */
- else if (access == ba_not_special)
- this_non_public = 1;
- else if (TREE_VIA_PROTECTED (base_binfo) && within_current_scope)
- ; /* no change */
- else if (is_friend (BINFO_TYPE (binfo), current_scope ()))
- ; /* no change */
- else
- this_non_public = 1;
-
- if (TREE_VIA_VIRTUAL (base_binfo))
- this_virtual = 1;
-
bk = lookup_base_r (base_binfo, base,
! access, within_current_scope,
! this_non_public, this_virtual,
binfo_ptr);
switch (bk)
{
case bk_ambig:
if (access != ba_any)
return bk;
found = bk;
break;
- case bk_inaccessible:
- if (found == bk_not_base)
- found = bk;
- my_friendly_assert (found == bk_via_virtual
- || found == bk_inaccessible, 20010723);
-
- break;
-
case bk_same_type:
bk = bk_proper_base;
/* FALLTHROUGH */
case bk_proper_base:
my_friendly_assert (found == bk_not_base, 20010723);
--- 214,238 ----
return bk_not_base;
for (i = TREE_VEC_LENGTH (bases); i--;)
{
tree base_binfo = TREE_VEC_ELT (bases, i);
base_kind bk;
bk = lookup_base_r (base_binfo, base,
! access,
! is_virtual || TREE_VIA_VIRTUAL (base_binfo),
binfo_ptr);
switch (bk)
{
case bk_ambig:
if (access != ba_any)
return bk;
found = bk;
break;
case bk_same_type:
bk = bk_proper_base;
/* FALLTHROUGH */
case bk_proper_base:
my_friendly_assert (found == bk_not_base, 20010723);
*************** lookup_base_r (binfo, base, access, with
*** 286,295 ****
--- 244,256 ----
found = bk;
break;
case bk_not_base:
break;
+
+ default:
+ abort ();
}
}
return found;
}
*************** lookup_base (t, base, access, kind_ptr)
*** 331,342 ****
/* Ensure that the types are instantiated. */
t = complete_type (TYPE_MAIN_VARIANT (t));
base = complete_type (TYPE_MAIN_VARIANT (base));
! bk = lookup_base_r (t_binfo, base, access & ~ba_quiet,
! 0, 0, 0, &binfo);
/* Check that the base is unambiguous and accessible. */
if (access != ba_any)
switch (bk)
{
--- 292,302 ----
/* Ensure that the types are instantiated. */
t = complete_type (TYPE_MAIN_VARIANT (t));
base = complete_type (TYPE_MAIN_VARIANT (base));
! bk = lookup_base_r (t_binfo, base, access, 0, &binfo);
/* Check that the base is unambiguous and accessible. */
if (access != ba_any)
switch (bk)
{
*************** adjust_result_of_qualified_name_lookup (
*** 1860,1873 ****
if (BASELINK_P (decl)
&& DERIVED_FROM_P (qualifying_class, context_class))
{
tree base;
! /* Look for the QUALIFYING_CLASS as a base of the
! CONTEXT_CLASS. If QUALIFYING_CLASS is ambiguous, we cannot
! be sure yet than an error has occurred; perhaps the function
! chosen by overload resolution will be static. */
base = lookup_base (context_class, qualifying_class,
ba_ignore | ba_quiet, NULL);
if (base)
{
BASELINK_ACCESS_BINFO (decl) = base;
--- 1820,1834 ----
if (BASELINK_P (decl)
&& DERIVED_FROM_P (qualifying_class, context_class))
{
tree base;
! /* Look for the QUALIFYING_CLASS as a base of the CONTEXT_CLASS.
! Because we do not yet know which function will be chosen by
! overload resolution, we cannot yet check either accessibility
! or ambiguity -- in either case, the choice of a static member
! function might make the usage valid. */
base = lookup_base (context_class, qualifying_class,
ba_ignore | ba_quiet, NULL);
if (base)
{
BASELINK_ACCESS_BINFO (decl) = base;
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.282.4.5
diff -c -5 -p -r1.282.4.5 semantics.c
*** cp/semantics.c 20 Jun 2003 03:06:28 -0000 1.282.4.5
--- cp/semantics.c 6 Jul 2003 21:53:34 -0000
*************** finish_call_expr (tree fn, tree args, bo
*** 1271,1281 ****
to `B'. We believe it refers to `B'. */
if (current_class_type
&& DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
current_class_type)
&& current_class_ref)
! object = current_class_ref;
else
{
tree representative_fn;
representative_fn = BASELINK_FUNCTIONS (fn);
--- 1271,1282 ----
to `B'. We believe it refers to `B'. */
if (current_class_type
&& DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
current_class_type)
&& current_class_ref)
! object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
! NULL);
else
{
tree representative_fn;
representative_fn = BASELINK_FUNCTIONS (fn);
Index: testsuite/g++.old-deja/g++.jason/access8.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.jason/access8.C,v
retrieving revision 1.4.20.1
diff -c -5 -p -r1.4.20.1 access8.C
*** testsuite/g++.old-deja/g++.jason/access8.C 26 Jun 2003 01:05:45 -0000 1.4.20.1
--- testsuite/g++.old-deja/g++.jason/access8.C 6 Jul 2003 21:53:39 -0000
*************** protected:
*** 18,28 ****
class top_t : protected mel {
public:
void myf(int);
};
! void inh::myf(int i) { // ERROR - inaccessible
a = i;
}
void top_t::myf(int i) {
inh::myf(i); // ERROR - cannot convert to inh
--- 18,28 ----
class top_t : protected mel {
public:
void myf(int);
};
! void inh::myf(int i) {
a = i;
}
void top_t::myf(int i) {
inh::myf(i); // ERROR - cannot convert to inh