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]

[C++ PATCH] Fix anonymous aggregates


Hi!

anon6.C below fails to compile (one gets errors about duplicate declarations
even if one declaration is e.g. in anonymous union inside of the base class
and the other is in the derived class).
Alexandre Oliva said to this:
> This case seems to fail to compile because of a mis-reading of
> [class.union]/2.  It says members of an anonymous union should have
> names distinct from the names of any other entity in the scope in
> which the anonymous union is declared.  It doesn't mean their names
> should be distinct from names in scope at the point in which it is
> declared.
but from looking at the code it just looks anonymous aggregates have not
been taken into account.
This patch seems to fix this by looking up first non-anynymous containing
context for the purpose of setting INHERITED_VALUE_BINDING_P.
Bootstrapped on i386-redhat-linux, no regressions.
Ok to commit?

2001-01-30  Jakub Jelinek  <jakub@redhat.com>

	* decl.c (push_class_binding): If DECL is in anonymous aggregate
	context, lookup its surrounding context.

	* g++.old-deja/g++.other/anon6.C: New test.
	* g++.old-deja/g++.other/anon7.C: New test.

--- gcc/cp/decl.c.jj	Sun Jan 28 12:36:36 2001
+++ gcc/cp/decl.c	Tue Jan 30 17:02:06 2001
@@ -1127,6 +1127,14 @@ push_class_binding (id, decl)
 	      context = CP_DECL_CONTEXT (decl);
 	    }
 
+	  /* Skip all nested anonymous unions from context.  */
+	  while (ANON_AGGR_TYPE_P (context))
+	    {
+	      if (TREE_CODE (TREE_CHAIN (context)) != TYPE_DECL)
+		abort ();
+	      context = CP_DECL_CONTEXT (TREE_CHAIN (context));
+	    }
+
 	  if (is_properly_derived_from (current_class_type, context))
 	    INHERITED_VALUE_BINDING_P (binding) = 1;
 	  else
--- gcc/testsuite/g++.old-deja/g++.other/anon6.C.jj	Tue Jan 30 17:05:08 2001
+++ gcc/testsuite/g++.old-deja/g++.other/anon6.C	Tue Jan 30 18:21:59 2001
@@ -0,0 +1,36 @@
+extern "C" void abort ();
+
+struct A {
+  union {
+    int a;
+    double b;
+    int d;
+  };
+  int c;
+};
+
+struct B : public A {
+  union {
+    double a;
+    void *c;
+  };
+  float b;
+  int e;
+};
+
+int main ()
+{
+  struct B b;
+
+  b.a = 1.5;
+  b.b = 2.5;
+  b.d = 1;
+  b.e = 2;
+  if (b.a != 1.5 || b.b != 2.5 || b.d != 1 || b.e != 2)
+    abort ();
+  b.c = &b.a;
+  b.d = b.e;
+  if (b.c != &b.a || b.d != 2)
+    abort ();
+  return 0;
+}
--- gcc/testsuite/g++.old-deja/g++.other/anon7.C.jj	Tue Jan 30 17:16:56 2001
+++ gcc/testsuite/g++.old-deja/g++.other/anon7.C	Tue Jan 30 17:22:52 2001
@@ -0,0 +1,24 @@
+// Build don't link:
+
+struct A {
+  union {
+    int a;	// ERROR - conflicts with previous declaration
+  };
+  int a;	// ERROR - 
+};
+
+struct B {
+  int b;	// ERROR - conflicts with previous declaration
+  union {
+    int b;	// ERROR - duplicate member
+  };		// ERROR - declaration of
+};
+
+struct C {
+  union {
+    int c;	// ERROR - conflicts with previous declaration
+  };
+  union {
+    int c;	// ERROR - duplicate member
+  };		// ERROR - declaration of
+};

	Jakub

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