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]

PATCH to avoid bogus warning



This patch avoids the warnings about private constructors and so forth
on code like:

  class S {
  public:
    static void f();

  private:
     S();
     S(const S&);
     ~S();
  };

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

Index: class.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.83
diff -c -p -r1.83 class.c
*** class.c	1998/09/09 02:14:51	1.83
--- class.c	1998/09/14 16:57:10
*************** static void modify_all_indirect_vtables 
*** 100,105 ****
--- 100,106 ----
  					       tree, tree));
  static void build_class_init_list PROTO((tree));
  static int finish_base_struct PROTO((tree, struct base_info *));
+ static int maybe_class_too_private_p PROTO((tree));
  
  /* Way of stacking language names.  */
  tree *current_lang_base, *current_lang_stack;
*************** grow_method (fndecl, method_vec_ptr)
*** 1897,1902 ****
--- 1898,1929 ----
      }
  }
  
+ /* Returns non-zero if T is the sort of class for which we should
+    check issue warnings like "all constructors are private".  */
+ 
+ static int
+ maybe_class_too_private_p (t)
+     tree t;
+ {
+   if (!warn_ctor_dtor_privacy)
+     /* The user doesn't want to here these warnings.  */
+     return 0;
+ 
+   if (CLASSTYPE_FRIEND_CLASSES (t) 
+       || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
+     /* The class has friends.  Maybe they can make use of the class,
+        even though it's very private.  */
+     return 0;
+ 
+   if (CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN (t))
+     /* The class has a non-private static member function.  Such a
+        thing might be used, like a friend, to create instances of the
+        class.  */
+     return 0;
+ 
+   return 1;
+ }
+ 
  /* Warn about duplicate methods in fn_fields.  Also compact method
     lists so that lookup can be made faster.
  
*************** finish_struct_methods (t, fn_fields, non
*** 2023,2031 ****
    obstack_finish (&class_obstack);
    CLASSTYPE_METHOD_VEC (t) = method_vec;
  
!   if (nonprivate_method == 0
!       && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
!       && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE)
      {
        tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
        for (i = 0; i < n_baseclasses; i++)
--- 2050,2056 ----
    obstack_finish (&class_obstack);
    CLASSTYPE_METHOD_VEC (t) = method_vec;
  
!   if (nonprivate_method == 0 && maybe_class_too_private_p (t))
      {
        tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
        for (i = 0; i < n_baseclasses; i++)
*************** finish_struct_methods (t, fn_fields, non
*** 2035,2042 ****
  	    nonprivate_method = 1;
  	    break;
  	  }
!       if (nonprivate_method == 0 
! 	  && warn_ctor_dtor_privacy)
  	cp_warning ("all member functions in class `%T' are private", t);
      }
  
--- 2060,2066 ----
  	    nonprivate_method = 1;
  	    break;
  	  }
!       if (nonprivate_method == 0)
  	cp_warning ("all member functions in class `%T' are private", t);
      }
  
*************** finish_struct_methods (t, fn_fields, non
*** 2049,2058 ****
        /* Wild parse errors can cause this to happen.  */
        if (dtor == NULL_TREE)
  	TYPE_HAS_DESTRUCTOR (t) = 0;
!       else if (TREE_PRIVATE (dtor)
! 	       && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
! 	       && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE
! 	       && warn_ctor_dtor_privacy)
  	cp_warning ("`%#T' only defines a private destructor and has no friends",
  		    t);
      }
--- 2073,2079 ----
        /* Wild parse errors can cause this to happen.  */
        if (dtor == NULL_TREE)
  	TYPE_HAS_DESTRUCTOR (t) = 0;
!       else if (TREE_PRIVATE (dtor) && maybe_class_too_private_p (t))
  	cp_warning ("`%#T' only defines a private destructor and has no friends",
  		    t);
      }
*************** finish_struct_1 (t, warn_anon)
*** 3629,3635 ****
  		break;
  	      }
  
! 	  if (nonprivate_ctor == 0 && warn_ctor_dtor_privacy)
  	    cp_warning ("`%#T' only defines private constructors and has no friends",
  			t);
  	}
--- 3650,3656 ----
  		break;
  	      }
  
! 	  if (nonprivate_ctor == 0 && maybe_class_too_private_p (t))
  	    cp_warning ("`%#T' only defines private constructors and has no friends",
  			t);
  	}
*************** finish_struct (t, list_of_fieldlists, at
*** 4207,4212 ****
--- 4228,4239 ----
  
  	  TREE_PRIVATE (x) = access == access_private_node;
  	  TREE_PROTECTED (x) = access == access_protected_node;
+ 
+ 	  if (!TREE_PRIVATE (x) 
+ 	      && TREE_CODE (x) == FUNCTION_DECL 
+ 	      && DECL_LANG_SPECIFIC (x)
+ 	      && DECL_STATIC_FUNCTION_P (x))
+ 	    CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN (t) = 1;
  
  	  if (TREE_CODE (x) == TEMPLATE_DECL)
  	    {
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.139
diff -c -p -r1.139 cp-tree.h
*** cp-tree.h	1998/09/09 02:14:53	1.139
--- cp-tree.h	1998/09/14 16:57:22
*************** struct lang_type
*** 621,631 ****
        unsigned has_complex_assign_ref : 1;
        unsigned has_abstract_assign_ref : 1;
        unsigned non_aggregate : 1;
  
        /* The MIPS compiler gets it wrong if this struct also
  	 does not fill out to a multiple of 4 bytes.  Add a
  	 member `dummy' with new bits if you go over the edge.  */
!       unsigned dummy : 11;
      } type_flags;
  
    int n_ancestors;
--- 621,632 ----
        unsigned has_complex_assign_ref : 1;
        unsigned has_abstract_assign_ref : 1;
        unsigned non_aggregate : 1;
+       unsigned has_non_private_static_mem_fn : 1;
  
        /* The MIPS compiler gets it wrong if this struct also
  	 does not fill out to a multiple of 4 bytes.  Add a
  	 member `dummy' with new bits if you go over the edge.  */
!       unsigned dummy : 10;
      } type_flags;
  
    int n_ancestors;
*************** extern int flag_new_for_scope;
*** 1450,1455 ****
--- 1451,1460 ----
    (TYPE_LANG_SPECIFIC (NODE)->type_flags.non_aggregate)
  #define TYPE_NON_AGGREGATE_CLASS(NODE) \
    (IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE))
+ 
+ /* Nonzero if NODE has a non-private static member function.  */
+ #define CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN(NODE) \
+   (TYPE_LANG_SPECIFIC (NODE)->type_flags.has_non_private_static_mem_fn)
  
  /* Nonzero if there is a user-defined X::op=(x&) for this class.  */
  #define TYPE_HAS_REAL_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_real_assign_ref)


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