PATCH for reference/qualified member confusion

Mark Mitchell mark@markmitchell.com
Thu Sep 3 19:38:00 GMT 1998


We used to crash on the following code.  Now we don't.

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

1998-09-03  Mark Mitchell  <mark@markmitchell.com>

	* init.c (resolve_offset_ref): Call convert_from_reference to
 	handle members of reference type.  Improve error recovery.

Index: testsuite/g++.old-deja/g++.other/crash5.C
===================================================================
RCS file: crash5.C
diff -N crash5.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- crash5.C	Thu Sep  3 19:21:49 1998
***************
*** 0 ****
--- 1,21 ----
+ // Build don't link:
+ 
+ class TecMesh {};
+ 
+ extern TecMesh& m;
+ 
+ struct X { 
+   X(TecMesh&);
+ };
+ 
+ struct D  {
+   D();
+   TecMesh& Mesh;
+ };
+ 
+ 
+ D::D ()
+   : Mesh(m)
+ {
+   X x(D::Mesh);
+ }
Index: cp/init.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/init.c,v
retrieving revision 1.62
diff -c -p -r1.62 init.c
*** init.c	1998/08/27 17:33:33	1.62
--- init.c	1998/09/04 02:22:58
*************** resolve_offset_ref (exp)
*** 1798,1804 ****
  	  || (TREE_CODE (base) == NOP_EXPR
  	      && TREE_OPERAND (base, 0) == error_mark_node)))
      {
!       tree basetype_path, access;
  
        if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
  	basetype = TYPE_OFFSET_BASETYPE (type);
--- 1798,1806 ----
  	  || (TREE_CODE (base) == NOP_EXPR
  	      && TREE_OPERAND (base, 0) == error_mark_node)))
      {
!       tree basetype_path;
!       tree access;
!       tree expr;
  
        if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
  	basetype = TYPE_OFFSET_BASETYPE (type);
*************** resolve_offset_ref (exp)
*** 1816,1837 ****
  	 convert_pointer_to will bash it.  */
        access = compute_access (basetype_path, member);
        addr = convert_pointer_to (basetype, base);
!       if (access == access_public_node)
! 	return build (COMPONENT_REF, TREE_TYPE (member),
! 		      build_indirect_ref (addr, NULL_PTR), member);
!       if (access == access_protected_node)
! 	{
! 	  cp_error_at ("member `%D' is protected", member);
! 	  error ("in this context");
! 	  return error_mark_node;
! 	}
!       if (access == access_private_node)
  	{
! 	  cp_error_at ("member `%D' is private", member);
! 	  error ("in this context");
! 	  return error_mark_node;
! 	}
!       my_friendly_abort (55);
      }
  
    /* Ensure that we have an object.  */
--- 1818,1840 ----
  	 convert_pointer_to will bash it.  */
        access = compute_access (basetype_path, member);
        addr = convert_pointer_to (basetype, base);
! 
!       /* Issue errors if there was an access violation.  */
!       if (access != access_public_node)
  	{
! 	  cp_error_at ("member `%D' is %s", 
! 		       access == access_private_node 
! 		       ? "private" : "protected",
! 		       member);
! 	  cp_error ("in this context");
! 	} 
! 
!       /* Even in the case of illegal access, we form the
! 	 COMPONENT_REF; that will allow better error recovery than
! 	 just feeding back error_mark_node.  */
!       expr = build (COMPONENT_REF, TREE_TYPE (member),
! 		    build_indirect_ref (addr, NULL_PTR), member);
!       return convert_from_reference (expr);
      }
  
    /* Ensure that we have an object.  */
*************** resolve_offset_ref (exp)
*** 1839,1851 ****
        && TREE_OPERAND (base, 0) == error_mark_node)
      addr = error_mark_node;
    else
!     {
!       /* If this is a reference to a member function, then return the
! 	 address of the member function (which may involve going
! 	 through the object's vtable), otherwise, return an expression
! 	 for the dereferenced pointer-to-member construct.  */
!       addr = build_unary_op (ADDR_EXPR, base, 0);
!     }
  
    if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE)
      {
--- 1842,1852 ----
        && TREE_OPERAND (base, 0) == error_mark_node)
      addr = error_mark_node;
    else
!     /* If this is a reference to a member function, then return the
!        address of the member function (which may involve going
!        through the object's vtable), otherwise, return an expression
!        for the dereferenced pointer-to-member construct.  */
!     addr = build_unary_op (ADDR_EXPR, base, 0);
  
    if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE)
      {
Index: cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.131
diff -c -p -r1.131 cp-tree.h
*** cp-tree.h	1998/09/03 16:09:56	1.131
--- cp-tree.h	1998/09/04 02:22:49
*************** extern tree finish_this_expr            
*** 2932,2938 ****
  extern tree finish_object_call_expr             PROTO((tree, tree, tree));
  extern tree finish_qualified_object_call_expr   PROTO((tree, tree, tree));
  extern tree finish_pseudo_destructor_call_expr  PROTO((tree, tree, tree));
! extern tree finish_globally_qualified_member_call_expr PROTO ((tree, tree));
  extern tree finish_label_address_expr           PROTO((tree));
  extern tree finish_unary_op_expr                PROTO((enum tree_code, tree));
  extern tree finish_id_expr                      PROTO((tree));
--- 2932,2938 ----
  extern tree finish_object_call_expr             PROTO((tree, tree, tree));
  extern tree finish_qualified_object_call_expr   PROTO((tree, tree, tree));
  extern tree finish_pseudo_destructor_call_expr  PROTO((tree, tree, tree));
! extern tree finish_qualified_call_expr          PROTO ((tree, tree));
  extern tree finish_label_address_expr           PROTO((tree));
  extern tree finish_unary_op_expr                PROTO((enum tree_code, tree));
  extern tree finish_id_expr                      PROTO((tree));
Index: cp/method.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/method.c,v
retrieving revision 1.72
diff -c -p -r1.72 method.c
*** method.c	1998/08/27 02:04:26	1.72
--- method.c	1998/09/04 02:23:04
*************** hack_identifier (value, name)
*** 1954,1960 ****
        return value;
      }
  
!   if (TREE_CODE (type) == REFERENCE_TYPE && ! processing_template_decl)
      value = convert_from_reference (value);
    return value;
  }
--- 1954,1960 ----
        return value;
      }
  
!   if (! processing_template_decl)
      value = convert_from_reference (value);
    return value;
  }
Index: cp/parse.y
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/parse.y,v
retrieving revision 1.86
diff -c -p -r1.86 parse.y
*** parse.y	1998/08/28 15:43:56	1.86
--- parse.y	1998/09/04 02:23:38
*************** primary:
*** 1491,1499 ****
  	| overqualified_id  %prec HYPERUNARY
  		{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
  	| overqualified_id '(' nonnull_exprlist ')'
!                 { $$ = finish_globally_qualified_member_call_expr ($1, $3); }
  	| overqualified_id LEFT_RIGHT
! 		{ $$ = finish_globally_qualified_member_call_expr ($1, NULL_TREE); }
          | object object_template_id %prec UNARY
                  { 
  		  $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); 
--- 1491,1499 ----
  	| overqualified_id  %prec HYPERUNARY
  		{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
  	| overqualified_id '(' nonnull_exprlist ')'
!                 { $$ = finish_qualified_call_expr ($1, $3); }
  	| overqualified_id LEFT_RIGHT
! 		{ $$ = finish_qualified_call_expr ($1, NULL_TREE); }
          | object object_template_id %prec UNARY
                  { 
  		  $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); 
Index: cp/semantics.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/semantics.c,v
retrieving revision 1.26
diff -c -p -r1.26 semantics.c
*** semantics.c	1998/09/01 11:51:41	1.26
--- semantics.c	1998/09/04 02:23:41
*************** finish_pseudo_destructor_call_expr (obje
*** 995,1001 ****
     ARGS.  Returns an expression for the call.  */
  
  tree 
! finish_globally_qualified_member_call_expr (fn, args)
       tree fn;
       tree args;
  {
--- 995,1001 ----
     ARGS.  Returns an expression for the call.  */
  
  tree 
! finish_qualified_call_expr (fn, args)
       tree fn;
       tree args;
  {



More information about the Gcc-patches mailing list