This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix anonymous aggregates (take 2)
- To: Jason Merrill <jason at redhat dot com>
- Subject: [C++ PATCH] Fix anonymous aggregates (take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Fri, 2 Feb 2001 14:01:51 -0500
- Cc: mark at codesourcery dot com, gcc-patches at gcc dot gnu dot org
- References: <20010130211604.A594@sunsite.ms.mff.cuni.cz> <u97l396kcr.fsf@casey.cambridge.redhat.com>
- Reply-To: Jakub Jelinek <jakub at redhat dot com>
On Fri, Feb 02, 2001 at 05:57:57PM +0000, Jason Merrill wrote:
> This should use context_for_name_lookup.
How about this?
While looking at context_for_name_lookup, I found that either
if (!context) context = global_namespace is redundant or the while loop does
not check for context == NULL_TREE properly, because CP_DECL_CONTEXT
guarantees context to be non-NULL and the loop exits only if context is
dereferenced to find out it is either not TYPE_P or it is not
ANON_AGGR_TYPE_P.
As
static union { union { int a; }; }; at global namespace has second types'
TYPE_CONTEXT NULL_TREE, I think my change is correct although I haven't
found any testcase which would segfault on it.
Ok to commit?
2001-02-02 Jakub Jelinek <jakub@redhat.com>
* decl.c (push_class_binding): Use context_for_name_lookup instead
of CP_DECL_CONTEXT.
* search.c (context_for_name_lookup): Remove static. Check for NULL
context in the loop.
* cp-tree.h (context_for_name_lookup): Add prototype.
* 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 Fri Feb 2 20:23:04 2001
@@ -1124,7 +1124,7 @@ push_class_binding (id, decl)
else
{
my_friendly_assert (DECL_P (decl), 0);
- context = CP_DECL_CONTEXT (decl);
+ context = context_for_name_lookup (decl);
}
if (is_properly_derived_from (current_class_type, context))
--- gcc/cp/search.c.jj Mon Jan 22 13:58:58 2001
+++ gcc/cp/search.c Fri Feb 2 20:58:59 2001
@@ -120,7 +120,6 @@ static tree bfs_walk
void *));
static tree lookup_field_queue_p PARAMS ((tree, void *));
static tree lookup_field_r PARAMS ((tree, void *));
-static tree context_for_name_lookup PARAMS ((tree));
static tree canonical_binfo PARAMS ((tree));
static tree shared_marked_p PARAMS ((tree, void *));
static tree shared_unmarked_p PARAMS ((tree, void *));
@@ -714,7 +713,7 @@ at_function_scope_p ()
/* Return the scope of DECL, as appropriate when doing name-lookup. */
-static tree
+tree
context_for_name_lookup (decl)
tree decl;
{
@@ -724,9 +723,9 @@ context_for_name_lookup (decl)
definition, the members of the anonymous union are considered to
have been defined in the scope in which the anonymous union is
declared. */
- tree context = CP_DECL_CONTEXT (decl);
+ tree context = DECL_CONTEXT (decl);
- while (TYPE_P (context) && ANON_AGGR_TYPE_P (context))
+ while (context && TYPE_P (context) && ANON_AGGR_TYPE_P (context))
context = TYPE_CONTEXT (context);
if (!context)
context = global_namespace;
--- gcc/cp/cp-tree.h.jj Thu Feb 1 13:52:47 2001
+++ gcc/cp/cp-tree.h Fri Feb 2 20:22:01 2001
@@ -4211,6 +4211,7 @@ extern void init_search_processing PARA
extern void reinit_search_statistics PARAMS ((void));
extern tree current_scope PARAMS ((void));
extern int at_function_scope_p PARAMS ((void));
+extern tree context_for_name_lookup PARAMS ((tree));
extern tree lookup_conversions PARAMS ((tree));
extern tree binfo_for_vtable PARAMS ((tree));
extern tree binfo_from_vbase PARAMS ((tree));
--- 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