This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: Fix access regression


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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]