Commit 096a4865 by Paolo Carlini Committed by Paolo Carlini

re PR c++/24926 (gcc ignores access level violation for anonymous structs)

/cp
2013-09-04  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/24926
	* class.c (finish_struct_anon_r): New.
	(finish_struct_anon): Use it.

/testsuite
2013-09-04  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/24926
	* g++.dg/parse/access11.C: New.

From-SVN: r202266
parent c167bc5b
2013-09-04 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/24926
* class.c (finish_struct_anon_r): New.
(finish_struct_anon): Use it.
2013-09-04 Gabriel Dos Reis <gdr@integrable-solutions.net> 2013-09-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
* cxx-pretty-print.h (cxx_pretty_printer::simple_type_specifier): * cxx-pretty-print.h (cxx_pretty_printer::simple_type_specifier):
......
...@@ -2773,24 +2773,11 @@ warn_hidden (tree t) ...@@ -2773,24 +2773,11 @@ warn_hidden (tree t)
} }
} }
/* Check for things that are invalid. There are probably plenty of other /* Recursive helper for finish_struct_anon. */
things we should check for also. */
static void static void
finish_struct_anon (tree t) finish_struct_anon_r (tree field, bool complain)
{ {
tree field;
for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
{
if (TREE_STATIC (field))
continue;
if (TREE_CODE (field) != FIELD_DECL)
continue;
if (DECL_NAME (field) == NULL_TREE
&& ANON_AGGR_TYPE_P (TREE_TYPE (field)))
{
bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE; bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE;
tree elt = TYPE_FIELDS (TREE_TYPE (field)); tree elt = TYPE_FIELDS (TREE_TYPE (field));
for (; elt; elt = DECL_CHAIN (elt)) for (; elt; elt = DECL_CHAIN (elt))
...@@ -2809,34 +2796,79 @@ finish_struct_anon (tree t) ...@@ -2809,34 +2796,79 @@ finish_struct_anon (tree t)
if (TREE_CODE (elt) != FIELD_DECL) if (TREE_CODE (elt) != FIELD_DECL)
{ {
if (complain)
{
if (is_union) if (is_union)
permerror (input_location, "%q+#D invalid; an anonymous union can " permerror (input_location,
"%q+#D invalid; an anonymous union can "
"only have non-static data members", elt); "only have non-static data members", elt);
else else
permerror (input_location, "%q+#D invalid; an anonymous struct can " permerror (input_location,
"%q+#D invalid; an anonymous struct can "
"only have non-static data members", elt); "only have non-static data members", elt);
}
continue; continue;
} }
if (complain)
{
if (TREE_PRIVATE (elt)) if (TREE_PRIVATE (elt))
{ {
if (is_union) if (is_union)
permerror (input_location, "private member %q+#D in anonymous union", elt); permerror (input_location,
"private member %q+#D in anonymous union", elt);
else else
permerror (input_location, "private member %q+#D in anonymous struct", elt); permerror (input_location,
"private member %q+#D in anonymous struct", elt);
} }
else if (TREE_PROTECTED (elt)) else if (TREE_PROTECTED (elt))
{ {
if (is_union) if (is_union)
permerror (input_location, "protected member %q+#D in anonymous union", elt); permerror (input_location,
"protected member %q+#D in anonymous union", elt);
else else
permerror (input_location, "protected member %q+#D in anonymous struct", elt); permerror (input_location,
"protected member %q+#D in anonymous struct", elt);
}
} }
TREE_PRIVATE (elt) = TREE_PRIVATE (field); TREE_PRIVATE (elt) = TREE_PRIVATE (field);
TREE_PROTECTED (elt) = TREE_PROTECTED (field); TREE_PROTECTED (elt) = TREE_PROTECTED (field);
/* Recurse into the anonymous aggregates to handle correctly
access control (c++/24926):
class A {
union {
union {
int i;
};
};
};
int j=A().i; */
if (DECL_NAME (elt) == NULL_TREE
&& ANON_AGGR_TYPE_P (TREE_TYPE (elt)))
finish_struct_anon_r (elt, /*complain=*/false);
} }
} }
/* Check for things that are invalid. There are probably plenty of other
things we should check for also. */
static void
finish_struct_anon (tree t)
{
for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
{
if (TREE_STATIC (field))
continue;
if (TREE_CODE (field) != FIELD_DECL)
continue;
if (DECL_NAME (field) == NULL_TREE
&& ANON_AGGR_TYPE_P (TREE_TYPE (field)))
finish_struct_anon_r (field, /*complain=*/true);
} }
} }
......
2013-09-04 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/24926
* g++.dg/parse/access11.C: New.
2013-09-04 David Edelsohn <dje.gcc@gmail.com> 2013-09-04 David Edelsohn <dje.gcc@gmail.com>
* g++.dg/warn/weak1.C: Skip on AIX. * g++.dg/warn/weak1.C: Skip on AIX.
......
// PR c++/24926
class A {
union {
int i; // { dg-error "private" }
};
union {
int j; // { dg-error "private" }
};
union {
union {
int k; // { dg-error "private" }
};
union {
union {
int l; // { dg-error "private" }
};
union {
int m; // { dg-error "private" }
union {
int n; // { dg-error "private" }
int o; // { dg-error "private" }
};
};
};
};
};
int a1 = A().i; // { dg-error "context" }
int a2 = A().j; // { dg-error "context" }
int a3 = A().k; // { dg-error "context" }
int a4 = A().l; // { dg-error "context" }
int a5 = A().m; // { dg-error "context" }
int a6 = A().n; // { dg-error "context" }
int a7 = A().o; // { dg-error "context" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment