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]
Other format: [Raw text]

C++ PATCH: PR 14401


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 "" }
+ };


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