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 to resolve_offset_ref for c++/2039


resolve_offset_ref wasn't clever enough to handle anonymous union members.
The solution is to hand off to build_component_ref, which is.  Down with
code duplication!

Tested i686-pc-linux-gnu, applied trunk and 3.1 branch.
Test in g++.dg/lookup/anon1.C.

2002-03-18  Jason Merrill  <jason@redhat.com>

	PR c++/2039
	* init.c (resolve_offset_ref): Hand off to build_component_ref.

*** init.c.~1~	Sun Mar 17 13:56:31 2002
--- init.c	Mon Mar 18 19:19:09 2002
*************** resolve_offset_ref (exp)
*** 1819,1827 ****
    if (TREE_CODE (member) == FIELD_DECL
        && (base == current_class_ref || is_dummy_object (base)))
      {
!       tree expr;
! 
!       basetype = DECL_CONTEXT (member);
  
        /* Try to get to basetype from 'this'; if that doesn't work,
           nothing will.  */
--- 1819,1825 ----
    if (TREE_CODE (member) == FIELD_DECL
        && (base == current_class_ref || is_dummy_object (base)))
      {
!       tree binfo = TYPE_BINFO (current_class_type);
  
        /* Try to get to basetype from 'this'; if that doesn't work,
           nothing will.  */
*************** resolve_offset_ref (exp)
*** 1829,1858 ****
  
        /* First convert to the intermediate base specified, if appropriate.  */
        if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
- 	base = build_scoped_ref (base, TYPE_OFFSET_BASETYPE (type));
- 
-       /* Don't check access on the conversion; we might be after a member
- 	 promoted by an access- or using-declaration, and we have already
- 	 checked access for the member itself.  */
-       basetype = lookup_base (TREE_TYPE (base), basetype, ba_ignore, NULL);
-       expr = build_base_path (PLUS_EXPR, base, basetype, 1);
- 
-       if (expr == error_mark_node)
- 	return error_mark_node;
- 
-       type = TREE_TYPE (member);
-       if (TREE_CODE (type) != REFERENCE_TYPE)
  	{
! 	  int quals = cp_type_quals (type) | cp_type_quals (TREE_TYPE (expr));
! 
! 	  if (DECL_MUTABLE_P (member))
! 	    quals &= ~TYPE_QUAL_CONST;
! 	  
! 	  type = cp_build_qualified_type (type, quals);
  	}
!       
!       expr = build (COMPONENT_REF, type, expr, member);
!       return convert_from_reference (expr);
      }
  
    /* Ensure that we have an object.  */
--- 1827,1841 ----
  
        /* First convert to the intermediate base specified, if appropriate.  */
        if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
  	{
! 	  binfo = binfo_or_else (TYPE_OFFSET_BASETYPE (type),
! 				 current_class_type);
! 	  if (!binfo)
! 	    return error_mark_node;
! 	  base = build_base_path (PLUS_EXPR, base, binfo, 1);
  	}
! 
!       return build_component_ref (base, member, binfo, 1);
      }
  
    /* Ensure that we have an object.  */
// PR c++/2039
// Test that a scoped reference to a member of an anonymous union member of
// a base class works properly.

// { dg-do run }

struct A
{
  long ia1;
  union
  {
    long ia2;
  };
};

struct B : public A
{
  void f1();
  void f2();
};

void B::f1()
{
  ia1 = 11;
  ia2 = 22;
}

void B::f2()
{
  ia1    = 33;
  A::ia2 = 44;   // <<< !!!????
}

int main()
{
  B x;

  x.f1();
  if (x.ia1 != 11 || x.ia2 != 22)
    return 1;

  x.f2();
  if (x.ia1 != 33 || x.ia2 != 44)
    return 1;

  return 0;
}

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