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 for c++/5645, c++/11159


Based on the comments in PR 11159, I modified Manuel's patch so that the compiler doesn't warn if the only user-defined constructor is the default constructor.

Tested x86_64-pc-linux-gnu, applied to trunk.

2008-02-14  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
	    Jason Merrill  <jason@redhat.com>

	PR c++/5645
	PR c++/11159
	* class.c (type_has_user_nondefault_constructor): New fn.
	* cp-tree.h: Declare it.
	* init.c (emit_mem_initializers): Use it for -W warning about
	missing base initializer.

Index: cp/init.c
===================================================================
*** cp/init.c	(revision 132281)
--- cp/init.c	(working copy)
*************** emit_mem_initializers (tree mem_inits)
*** 829,840 ****
        tree subobject = TREE_PURPOSE (mem_inits);
        tree arguments = TREE_VALUE (mem_inits);
  
!       /* If these initializations are taking place in a copy
! 	 constructor, the base class should probably be explicitly
! 	 initialized.  */
        if (extra_warnings && !arguments
  	  && DECL_COPY_CONSTRUCTOR_P (current_function_decl)
! 	  && TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (subobject)))
  	warning (OPT_Wextra, "%Jbase class %q#T should be explicitly initialized in the "
  		 "copy constructor",
  		 current_function_decl, BINFO_TYPE (subobject));
--- 829,841 ----
        tree subobject = TREE_PURPOSE (mem_inits);
        tree arguments = TREE_VALUE (mem_inits);
  
!       /* If these initializations are taking place in a copy constructor,
! 	 the base class should probably be explicitly initialized if there
! 	 is a user-defined constructor in the base class (other than the
! 	 default constructor, which will be called anyway).  */
        if (extra_warnings && !arguments
  	  && DECL_COPY_CONSTRUCTOR_P (current_function_decl)
! 	  && type_has_user_nondefault_constructor (BINFO_TYPE (subobject)))
  	warning (OPT_Wextra, "%Jbase class %q#T should be explicitly initialized in the "
  		 "copy constructor",
  		 current_function_decl, BINFO_TYPE (subobject));
Index: cp/class.c
===================================================================
*** cp/class.c	(revision 132281)
--- cp/class.c	(working copy)
*************** clone_constructors_and_destructors (tree
*** 4039,4044 ****
--- 4039,4066 ----
      clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1);
  }
  
+ /* Returns true iff class T has a user-defined constructor other than
+    the default constructor.  */
+ 
+ bool
+ type_has_user_nondefault_constructor (tree t)
+ {
+   tree fns;
+ 
+   if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+     return false;
+ 
+   for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+     {
+       tree fn = OVL_CURRENT (fns);
+       if (!DECL_ARTIFICIAL (fn)
+ 	  && skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn)) != NULL_TREE)
+ 	return true;
+     }
+ 
+   return false;
+ }
+ 
  /* Remove all zero-width bit-fields from T.  */
  
  static void
Index: cp/cp-tree.h
===================================================================
*** cp/cp-tree.h	(revision 132281)
--- cp/cp-tree.h	(working copy)
*************** extern void determine_key_method		(tree)
*** 4157,4162 ****
--- 4157,4163 ----
  extern void check_for_override			(tree, tree);
  extern void push_class_stack			(void);
  extern void pop_class_stack			(void);
+ extern bool type_has_user_nondefault_constructor (tree);
  
  /* in cvt.c */
  extern tree convert_to_reference		(tree, tree, int, int, tree);
Index: testsuite/g++.dg/warn/pr5645.C
===================================================================
*** testsuite/g++.dg/warn/pr5645.C	(revision 0)
--- testsuite/g++.dg/warn/pr5645.C	(revision 0)
***************
*** 0 ****
--- 1,32 ----
+ // PR5645: gcc warns that pure virtual class not explicitly initialized.  
+ // { dg-do compile }
+ // { dg-options "-Wall -Wextra" }
+ 
+ class a {
+ public:
+   virtual int f() = 0;
+   virtual int g() = 0;
+ };
+ 
+ class b : public a {
+ public:
+   b();
+   b(const b& c);
+ 
+ protected:
+   int i;
+ };
+ 
+ b::b() {}
+ 
+ b::b(const b& c) { // { dg-bogus "base class .class a. should be explicitly initialized in the copy constructor" }
+   i = c.i;
+ }
+ 
+ struct X {};
+ 
+ struct Y : X
+ {
+   Y (Y const&) {}
+ };
+ 
Index: testsuite/g++.dg/warn/Wreorder-1.C
===================================================================
*** testsuite/g++.dg/warn/Wreorder-1.C	(revision 132243)
--- testsuite/g++.dg/warn/Wreorder-1.C	(working copy)
*************** struct T {
*** 10,14 ****
  
  struct U : virtual public S, virtual public T {
    U () : T (), S () {}     // { dg-warning "" }
!   U (const U&) : S () {}   // { dg-warning "copy" }
  };
--- 10,14 ----
  
  struct U : virtual public S, virtual public T {
    U () : T (), S () {}     // { dg-warning "" }
!   U (const U&) : S () {}
  };
Index: testsuite/g++.dg/warn/pr11159.C
===================================================================
*** testsuite/g++.dg/warn/pr11159.C	(revision 0)
--- testsuite/g++.dg/warn/pr11159.C	(revision 0)
***************
*** 0 ****
--- 1,37 ----
+ // PR c++/11159 : erroneous warning in copy ctor with virtual inheritance
+ // { dg-do compile }
+ // { dg-options "-Wall -Wextra" }
+ struct A
+ {
+   A ();
+ };
+ 
+ struct B : virtual A
+ {
+   B ();
+ };
+ 
+ struct C : virtual A
+ {
+   C ();
+ };
+ 
+ struct D : B, C
+ {
+   D (D const&){}
+ };
+ 
+ template <typename Base>
+ struct E : Base
+ {
+   E ();
+ 
+   E (E const &)
+     : Base ()
+   {
+   };
+ };
+ 
+ E<C> foo;
+ E<C> bar (foo);
+ 

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