This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to resolve_offset_ref for c++/2039
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 18 Mar 2002 19:41:47 +0000
- Subject: 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;
}