This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 14401
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 9 Mar 2004 00:18:18 -0800
- Subject: C++ PATCH: PR 14401
- Reply-to: mark at codesourcery dot com
This patch fixes PR c++/14401, where we failed to complain about
various invalid classes and/or their constructors.
Tested on i686-pc-linux-gnu, applied on the mainline and on the 3.4
branch.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2004-03-08 Mark Mitchell <mark@codesourcery.com>
PR c++/14401
* class.c (check_field_decls): Complain about non-static data
members of reference type in unions. Propagate
CLASSTYPE_REF_FIELDS_NEED_INIT and
CLASSTYPE_READONLY_FIELDS_NEED_INIT from the types of non-static
data members.
* init.c (perform_member_init): Complain about mbmers with const
type that are not explicitly initialized.
2004-03-08 Mark Mitchell <mark@codesourcery.com>
PR c++/14401
* g++.dg/init/ctor3.C: New test.
* g++.dg/init/union1.C: New test.
* g++.dg/ext/anon-struct4.C: New test.
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.595.4.6
diff -c -5 -p -r1.595.4.6 class.c
*** cp/class.c 29 Feb 2004 23:04:12 -0000 1.595.4.6
--- cp/class.c 9 Mar 2004 07:22:18 -0000
*************** check_field_decls (tree t, tree *access_
*** 2921,2933 ****
|| TREE_CODE (x) == TEMPLATE_DECL)
continue;
/* If we've gotten this far, it's a data member, possibly static,
or an enumerator. */
-
DECL_CONTEXT (x) = t;
/* ``A local class cannot have static data members.'' ARM 9.4 */
if (current_function_decl && TREE_STATIC (x))
cp_error_at ("field `%D' in local class cannot be static", x);
/* Perform error checking that did not get done in
--- 2921,2954 ----
|| TREE_CODE (x) == TEMPLATE_DECL)
continue;
/* If we've gotten this far, it's a data member, possibly static,
or an enumerator. */
DECL_CONTEXT (x) = t;
+ /* When this goes into scope, it will be a non-local reference. */
+ DECL_NONLOCAL (x) = 1;
+
+ if (TREE_CODE (t) == UNION_TYPE)
+ {
+ /* [class.union]
+
+ If a union contains a static data member, or a member of
+ reference type, the program is ill-formed. */
+ if (TREE_CODE (x) == VAR_DECL)
+ {
+ cp_error_at ("`%D' may not be static because it is a member of a union", x);
+ continue;
+ }
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ cp_error_at ("`%D' may not have reference type `%T' because it is a member of a union",
+ x, type);
+ continue;
+ }
+ }
+
/* ``A local class cannot have static data members.'' ARM 9.4 */
if (current_function_decl && TREE_STATIC (x))
cp_error_at ("field `%D' in local class cannot be static", x);
/* Perform error checking that did not get done in
*************** check_field_decls (tree t, tree *access_
*** 2947,2971 ****
}
if (type == error_mark_node)
continue;
! /* When this goes into scope, it will be a non-local reference. */
! DECL_NONLOCAL (x) = 1;
!
! if (TREE_CODE (x) == CONST_DECL)
continue;
- if (TREE_CODE (x) == VAR_DECL)
- {
- if (TREE_CODE (t) == UNION_TYPE)
- /* Unions cannot have static members. */
- cp_error_at ("field `%D' declared static in union", x);
-
- continue;
- }
-
/* Now it can only be a FIELD_DECL. */
if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
CLASSTYPE_NON_AGGREGATE (t) = 1;
--- 2968,2980 ----
}
if (type == error_mark_node)
continue;
! if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)
continue;
/* Now it can only be a FIELD_DECL. */
if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
CLASSTYPE_NON_AGGREGATE (t) = 1;
*************** check_field_decls (tree t, tree *access_
*** 2991,3000 ****
--- 3000,3017 ----
type = strip_array_types (type);
if (TYPE_PTR_P (type))
has_pointers = 1;
+
+ if (CLASS_TYPE_P (type))
+ {
+ if (CLASSTYPE_REF_FIELDS_NEED_INIT (type))
+ SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
+ if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
+ SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
+ }
if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
CLASSTYPE_HAS_MUTABLE (t) = 1;
if (! pod_type_p (type))
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.356.2.6
diff -c -5 -p -r1.356.2.6 init.c
*** cp/init.c 2 Mar 2004 19:57:05 -0000 1.356.2.6
--- cp/init.c 9 Mar 2004 07:22:18 -0000
*************** perform_member_init (tree member, tree i
*** 369,378 ****
--- 369,381 ----
member);
}
/* member traversal: note it leaves init NULL */
else if (TREE_CODE (type) == REFERENCE_TYPE)
pedwarn ("uninitialized reference member `%D'", member);
+ else if (CP_TYPE_CONST_P (type))
+ pedwarn ("uninitialized mber `%D' with `const' type `%T'",
+ member, type);
}
else if (TREE_CODE (init) == TREE_LIST)
/* There was an explicit member initialization. Do some work
in that case. */
init = build_x_compound_expr_from_list (init, "member initializer");
Index: testsuite/g++.dg/ext/anon-struct4.C
===================================================================
RCS file: testsuite/g++.dg/ext/anon-struct4.C
diff -N testsuite/g++.dg/ext/anon-struct4.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/ext/anon-struct4.C 9 Mar 2004 07:22:19 -0000
***************
*** 0 ****
--- 1,3 ----
+ // PR c++/14401
+
+ struct { struct { int& i ; } bar ; } foo ; // { dg-error "" }
Index: testsuite/g++.dg/init/ctor3.C
===================================================================
RCS file: testsuite/g++.dg/init/ctor3.C
diff -N testsuite/g++.dg/init/ctor3.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/init/ctor3.C 9 Mar 2004 07:22:19 -0000
***************
*** 0 ****
--- 1,6 ----
+ // PR c++/14401
+
+ struct S {
+ S() {} // { dg-error "" }
+ const int i;
+ };
Index: testsuite/g++.dg/init/union1.C
===================================================================
RCS file: testsuite/g++.dg/init/union1.C
diff -N testsuite/g++.dg/init/union1.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/init/union1.C 9 Mar 2004 07:22:19 -0000
***************
*** 0 ****
--- 1,5 ----
+ // PR c++/14401
+
+ union U {
+ int& i; // { dg-error "" }
+ };