This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Fix access regression
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 24 Jul 2003 16:32:59 -0700
- Subject: C++ PATCH: Fix access regression
- Reply-to: mark at codesourcery dot com
My recent patch:
2003-07-23 Mark Mitchell <mark@codesourcery.com>
PR c++/11645
* cp-tree.h (accessible_base_p): Declare.
* call.c (build_over_call): Use it.
* search.c (accessible_base_p): New function, split out from ...
(lookup_base): ... here.
caused a regression. (We noticed this through our nightly test runs.)
Tested on i686-pc-linux-gnu, applied on the mainline and on the
branch.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2003-07-24 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (convert_to_base_statically): Declare.
* call.c (build_special_member_call): Convert INSTANCE to the base
type.
* class.c (convert_to_base_statically): New method.
* init.c (construct_virtual_base): Use it.
* method.c (do_build_assign_ref): Fix typo in comment.
2003-07-24 Mark Mitchell <mark@codesourcery.com>
* g++.dg/inherit/access5.C: New test.
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.414
diff -c -5 -p -r1.414 call.c
*** cp/call.c 23 Jul 2003 21:28:23 -0000 1.414
--- cp/call.c 24 Jul 2003 23:26:58 -0000
*************** build_special_member_call (tree instance
*** 4745,4759 ****
{
instance = build_int_2 (0, 0);
TREE_TYPE (instance) = build_pointer_type (class_type);
instance = build1 (INDIRECT_REF, class_type, instance);
}
! else if (name == complete_dtor_identifier
! || name == base_dtor_identifier
! || name == deleting_dtor_identifier)
! my_friendly_assert (args == NULL_TREE, 20020712);
!
my_friendly_assert (instance != NULL_TREE, 20020712);
/* Resolve the name. */
if (!complete_type_or_else (BINFO_TYPE (binfo), NULL_TREE))
return error_mark_node;
--- 4745,4771 ----
{
instance = build_int_2 (0, 0);
TREE_TYPE (instance) = build_pointer_type (class_type);
instance = build1 (INDIRECT_REF, class_type, instance);
}
! else
! {
! if (name == complete_dtor_identifier
! || name == base_dtor_identifier
! || name == deleting_dtor_identifier)
! my_friendly_assert (args == NULL_TREE, 20020712);
!
! /* We must perform the conversion here so that we do not
! subsequently check to see whether BINFO is an accessible
! base. (It is OK for a constructor to call a constructor in
! an inaccessible base as long as the constructor being called
! is accessible.) */
! if (!same_type_ignoring_top_level_qualifiers_p
! (TREE_TYPE (instance), BINFO_TYPE (binfo)))
! instance = convert_to_base_statically (instance, binfo);
! }
!
my_friendly_assert (instance != NULL_TREE, 20020712);
/* Resolve the name. */
if (!complete_type_or_else (BINFO_TYPE (binfo), NULL_TREE))
return error_mark_node;
*************** build_special_member_call (tree instance
*** 4785,4795 ****
BINFO_SUBVTT_INDEX (binfo));
args = tree_cons (NULL_TREE, sub_vtt, args);
}
! return build_new_method_call (instance, fns, args, binfo, flags);
}
/* Return the NAME, as a C string. The NAME indicates a function that
is a member of TYPE. *FREE_P is set to true if the caller must
free the memory returned.
--- 4797,4809 ----
BINFO_SUBVTT_INDEX (binfo));
args = tree_cons (NULL_TREE, sub_vtt, args);
}
! return build_new_method_call (instance, fns, args,
! TYPE_BINFO (BINFO_TYPE (binfo)),
! flags);
}
/* Return the NAME, as a C string. The NAME indicates a function that
is a member of TYPE. *FREE_P is set to true if the caller must
free the memory returned.
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.556
diff -c -5 -p -r1.556 class.c
*** cp/class.c 22 Jul 2003 23:30:11 -0000 1.556
--- cp/class.c 24 Jul 2003 23:26:58 -0000
*************** convert_to_base (tree object, tree type,
*** 389,398 ****
--- 389,425 ----
return error_mark_node;
return build_base_path (PLUS_EXPR, object, binfo, /*nonnull=*/1);
}
+ /* EXPR is an expression with class type. BASE is a base class (a
+ BINFO) of that class type. Returns EXPR, converted to the BASE
+ type. This function assumes that EXPR is the most derived class;
+ therefore virtual bases can be found at their static offsets. */
+
+ tree
+ convert_to_base_statically (tree expr, tree base)
+ {
+ tree expr_type;
+
+ expr_type = TREE_TYPE (expr);
+ if (!same_type_p (expr_type, BINFO_TYPE (base)))
+ {
+ tree pointer_type;
+
+ pointer_type = build_pointer_type (expr_type);
+ expr = build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1);
+ if (!integer_zerop (BINFO_OFFSET (base)))
+ expr = build (PLUS_EXPR, pointer_type, expr,
+ build_nop (pointer_type, BINFO_OFFSET (base)));
+ expr = build_nop (build_pointer_type (BINFO_TYPE (base)), expr);
+ expr = build1 (INDIRECT_REF, BINFO_TYPE (base), expr);
+ }
+
+ return expr;
+ }
+
/* Virtual function things. */
static tree
build_vtable_entry_ref (tree array_ref, tree instance, tree idx)
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.885
diff -c -5 -p -r1.885 cp-tree.h
*** cp/cp-tree.h 23 Jul 2003 21:28:23 -0000 1.885
--- cp/cp-tree.h 24 Jul 2003 23:26:59 -0000
*************** extern tree in_charge_arg_for_name (tree
*** 3559,3568 ****
--- 3559,3569 ----
extern tree build_cxx_call (tree, tree, tree);
/* in class.c */
extern tree build_base_path (enum tree_code, tree, tree, int);
extern tree convert_to_base (tree, tree, bool);
+ extern tree convert_to_base_statically (tree, tree);
extern tree build_vtbl_ref (tree, tree);
extern tree build_vfn_ref (tree, tree);
extern tree get_vtable_decl (tree, int);
extern void resort_type_method_vec
(void *, void *, gt_pointer_operator, void *);
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.332
diff -c -5 -p -r1.332 init.c
*** cp/init.c 22 Jul 2003 23:30:15 -0000 1.332
--- cp/init.c 24 Jul 2003 23:26:59 -0000
*************** construct_virtual_base (tree vbase, tree
*** 861,882 ****
/* Compute the location of the virtual base. If we're
constructing virtual bases, then we must be the most derived
class. Therefore, we don't have to look up the virtual base;
we already know where it is. */
! exp = build (PLUS_EXPR,
! TREE_TYPE (current_class_ptr),
! current_class_ptr,
! fold (build1 (NOP_EXPR, TREE_TYPE (current_class_ptr),
! BINFO_OFFSET (vbase))));
! exp = build1 (NOP_EXPR,
! build_pointer_type (BINFO_TYPE (vbase)),
! exp);
! exp = build1 (INDIRECT_REF, BINFO_TYPE (vbase), exp);
! expand_aggr_init_1 (vbase, current_class_ref, exp,
! arguments, LOOKUP_COMPLAIN);
finish_compound_stmt (/*has_no_scope=*/1, compound_stmt);
finish_then_clause (inner_if_stmt);
finish_if_stmt ();
expand_cleanup_for_base (vbase, flag);
--- 861,874 ----
/* Compute the location of the virtual base. If we're
constructing virtual bases, then we must be the most derived
class. Therefore, we don't have to look up the virtual base;
we already know where it is. */
! exp = convert_to_base_statically (current_class_ref, vbase);
! expand_aggr_init_1 (vbase, current_class_ref, exp, arguments,
! LOOKUP_COMPLAIN);
finish_compound_stmt (/*has_no_scope=*/1, compound_stmt);
finish_then_clause (inner_if_stmt);
finish_if_stmt ();
expand_cleanup_for_base (vbase, flag);
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.262
diff -c -5 -p -r1.262 method.c
*** cp/method.c 21 Jul 2003 08:28:33 -0000 1.262
--- cp/method.c 24 Jul 2003 23:26:59 -0000
*************** do_build_assign_ref (tree fndecl)
*** 603,613 ****
{
tree fields;
int cvquals = cp_type_quals (TREE_TYPE (parm));
int i;
! /* Assign to each of thedirect base classes. */
for (i = 0; i < CLASSTYPE_N_BASECLASSES (current_class_type); ++i)
{
tree binfo;
tree converted_parm;
--- 603,613 ----
{
tree fields;
int cvquals = cp_type_quals (TREE_TYPE (parm));
int i;
! /* Assign to each of the direct base classes. */
for (i = 0; i < CLASSTYPE_N_BASECLASSES (current_class_type); ++i)
{
tree binfo;
tree converted_parm;
Index: testsuite/g++.dg/inherit/access5.C
===================================================================
RCS file: testsuite/g++.dg/inherit/access5.C
diff -N testsuite/g++.dg/inherit/access5.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/access5.C 24 Jul 2003 23:27:00 -0000
***************
*** 0 ****
--- 1,4 ----
+ struct S { ~S(); };
+ struct T : virtual private S {};
+ struct U : private T {};
+ U u;