re PR c++/2039 (bad code generated for access to unnamed union in base class)
PR c++/2039 * init.c (resolve_offset_ref): Hand off to build_component_ref. From-SVN: r50991
This commit is contained in:
parent
c2d8e20aff
commit
097955f2b0
3 changed files with 58 additions and 25 deletions
|
@ -1,5 +1,8 @@
|
|||
2002-03-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/2039
|
||||
* init.c (resolve_offset_ref): Hand off to build_component_ref.
|
||||
|
||||
PR c++/4222, c++/5995
|
||||
* call.c (build_over_call): Fix empty class logic.
|
||||
|
||||
|
|
|
@ -1819,9 +1819,7 @@ resolve_offset_ref (exp)
|
|||
if (TREE_CODE (member) == FIELD_DECL
|
||||
&& (base == current_class_ref || is_dummy_object (base)))
|
||||
{
|
||||
tree expr;
|
||||
|
||||
basetype = DECL_CONTEXT (member);
|
||||
tree binfo = TYPE_BINFO (current_class_type);
|
||||
|
||||
/* Try to get to basetype from 'this'; if that doesn't work,
|
||||
nothing will. */
|
||||
|
@ -1829,30 +1827,15 @@ resolve_offset_ref (exp)
|
|||
|
||||
/* 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);
|
||||
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);
|
||||
}
|
||||
|
||||
expr = build (COMPONENT_REF, type, expr, member);
|
||||
return convert_from_reference (expr);
|
||||
|
||||
return build_component_ref (base, member, binfo, 1);
|
||||
}
|
||||
|
||||
/* Ensure that we have an object. */
|
||||
|
|
47
gcc/testsuite/g++.dg/lookup/anon1.C
Normal file
47
gcc/testsuite/g++.dg/lookup/anon1.C
Normal file
|
@ -0,0 +1,47 @@
|
|||
// 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue