OSDN Git Service

PR c++/2039
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 18 Mar 2002 19:44:29 +0000 (19:44 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 18 Mar 2002 19:44:29 +0000 (19:44 +0000)
        * init.c (resolve_offset_ref): Hand off to build_component_ref.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@50991 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/testsuite/g++.dg/lookup/anon1.C [new file with mode: 0644]

index 12d865e..6b791d5 100644 (file)
@@ -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.
 
index 54954de..53c9eef 100644 (file)
@@ -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.  */
diff --git a/gcc/testsuite/g++.dg/lookup/anon1.C b/gcc/testsuite/g++.dg/lookup/anon1.C
new file mode 100644 (file)
index 0000000..e4db50d
--- /dev/null
@@ -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;
+}