PATCH to avoid bogus warning

Mark Mitchell mark@markmitchell.com
Tue Sep 15 13:03:00 GMT 1998


>>>>> "Jason" == Jason Merrill <jason@cygnus.com> writes:

    >> Your suggestion would entail passing the variable around a bit:
    >> we'd actually create the variable in finish_struct and then
    >> pass it into finish_struct_methods and finish_struct_1.

    Jason> Seems like we could create it in finish_struct_1 and not
    Jason> use it in finish_struct_methods, since there we're looking
    Jason> for non-private methods already.

Well, it wasn't quite that simple.  I bit the bullet and cleaned up
the code to generate these warnings a bit, with the following patch,
which also allowed localizing the warning code.

The only real behaviorial change with this patch is w.r.t. templates;
before we issued the warning on every instantiation, now we issue it
only once, on the declaration itself.  There's no need to warn over
and over again, and making everything private is a design bug so
warning once early is better than many times later.  This change
required tweaks to a few tests in the test-suite.

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

1998-09-15  Mark Mitchell  <mark@markmitchell.com>

	* cp-tree.h: Revert previous change.
	(finish_struct_methods): Remove declaration.
	* class.c: Revert previous change.
	(maybe_warn_about_overly_private_class): New function.
	(finish_struct_methods): Declare here, and make static.  Remove
	unnecessary parameters.  Tidy slightly.  Use
	maybe_warn_about_overly_private_class. 
	(finish_struct_1): Adjust.  Remove check for private constructors,
	now done elsewhere.
	(finish_struct): Adjust.
	
Index: cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.140
diff -c -p -r1.140 cp-tree.h
*** cp-tree.h	1998/09/14 11:09:03	1.140
--- cp-tree.h	1998/09/15 18:01:35
*************** struct lang_type
*** 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;
--- 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;
*************** extern int flag_new_for_scope;
*** 1452,1461 ****
  #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)
  #define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_complex_assign_ref)
--- 1451,1456 ----
*************** extern tree get_vfield_offset			PROTO((t
*** 2414,2420 ****
  extern void duplicate_tag_error			PROTO((tree));
  extern tree finish_struct			PROTO((tree, tree, tree, int));
  extern tree finish_struct_1			PROTO((tree, int));
- extern tree finish_struct_methods		PROTO((tree, tree, int));
  extern int resolves_to_fixed_type_p		PROTO((tree, int *));
  extern void init_class_processing		PROTO((void));
  extern int is_empty_class			PROTO((tree));
--- 2409,2414 ----
Index: cp/class.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.84
diff -c -p -r1.84 class.c
*** class.c	1998/09/14 11:09:05	1.84
--- class.c	1998/09/15 18:01:52
*************** static void modify_all_indirect_vtables 
*** 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;
--- 100,107 ----
  					       tree, tree));
  static void build_class_init_list PROTO((tree));
  static int finish_base_struct PROTO((tree, struct base_info *));
! static void finish_struct_methods PROTO((tree));
! static void maybe_warn_about_overly_private_class PROTO ((tree));
  
  /* Way of stacking language names.  */
  tree *current_lang_base, *current_lang_stack;
*************** grow_method (fndecl, method_vec_ptr)
*** 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.
  
--- 1899,2043 ----
      }
  }
  
! /* Issue warnings about T having private constructors, but no friends,
!    and so forth.  
  
!    HAS_NONPRIVATE_METHOD is nonzero if T has any non-private methods or
!    static members.  HAS_NONPRIVATE_STATIC_FN is nonzero if T has any
!    non-private static member functions.  */
! 
! static void
! maybe_warn_about_overly_private_class (t)
!      tree t;
  {
!   if (warn_ctor_dtor_privacy
!       /* If the class has friends, those entities might create and
! 	 access instances, so we should not warn.  */
!       && !(CLASSTYPE_FRIEND_CLASSES (t)
! 	   || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
!       /* We will have warned when the template was declared; there's
! 	 no need to warn on every instantiation.  */
!       && !CLASSTYPE_TEMPLATE_INSTANTIATION (t))
!     {
!       /* We only issue one warning, if more than one applies, because
! 	 otherwise, on code like:
! 
! 	   class A {
! 	     // Oops - forgot `public:'
! 	     A();
! 	     A(const A&);
! 	     ~A();
! 	   };
! 
! 	 we warn several times about essentially the same problem.  */
! 
!       int has_member_fn = 0;
!       int has_nonprivate_method = 0;
!       tree fn;
! 
!       /* Check to see if all (non-constructor, non-destructor) member
! 	 functions are private.  (Since there are no friends or
! 	 non-private statics, we can't ever call any of the private
! 	 member functions.)  */
!       for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
! 	/* We're not interested in compiler-generated methods; they
! 	   don't provide any way to call private members.  */
! 	if (!DECL_ARTIFICIAL (fn)) 
! 	  {
! 	    if (!TREE_PRIVATE (fn))
! 	      {
! 		if (DECL_STATIC_FUNCTION_P (fn)) 
! 		  /* A non-private static member function is just like a
! 		     friend; it can create and invoke private member
! 		     functions, and be accessed without a class
! 		     instance.  */
! 		  return;
! 		
! 		has_nonprivate_method = 1;
! 		break;
! 	      }
! 	    else
! 	      has_member_fn = 1;
! 	  } 
  
!       if (!has_nonprivate_method && has_member_fn) 
! 	{
! 	  int i;
! 	  tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
! 	  for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++)
! 	    if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i))
! 		|| TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i)))
! 	      {
! 		has_nonprivate_method = 1;
! 		break;
! 	      }
! 	  if (!has_nonprivate_method) 
! 	    {
! 	      cp_warning ("all member functions in class `%T' are private", t);
! 	      return;
! 	    }
! 	}
  
!       /* Even if some of the member functions are non-private, the
! 	 class won't be useful for much if all the constructors or
! 	 destructors are private: such an object can never be created
! 	 or destroyed.  */
!       if (TYPE_HAS_DESTRUCTOR (t))
! 	{
! 	  tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1);
! 
! 	  if (TREE_PRIVATE (dtor))
! 	    {
! 	      cp_warning ("`%#T' only defines a private destructor and has no friends",
! 			  t);
! 	      return;
! 	    }
! 	}
! 
!       if (TYPE_HAS_CONSTRUCTOR (t))
! 	{
! 	  int nonprivate_ctor = 0;
! 	  
! 	  /* If a non-template class does not define a copy
! 	     constructor, one is defined for it, enabling it to avoid
! 	     this warning.  For a template class, this does not
! 	     happen, and so we would normally get a warning on:
! 
! 	       template <class T> class C { private: C(); };  
! 	  
! 	     To avoid this asymmetry, we check TYPE_HAS_INIT_REF.  */ 
! 	  if (!TYPE_HAS_INIT_REF (t))
! 	    nonprivate_ctor = 1;
! 	  else 
! 	    for (fn = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
! 		 fn;
! 		 fn = OVL_NEXT (fn)) 
! 	      {
! 		tree ctor = OVL_CURRENT (fn);
! 		/* Ideally, we wouldn't count copy constructors (or, in
! 		   fact, any constructor that takes an argument of the
! 		   class type as a parameter) because such things cannot
! 		   be used to construct an instance of the class unless
! 		   you already have one.  But, for now at least, we're
! 		   more generous.  */
! 		if (! TREE_PRIVATE (ctor))
! 		  {
! 		    nonprivate_ctor = 1;
! 		    break;
! 		  }
! 	      }
  
! 	  if (nonprivate_ctor == 0)
! 	    {
! 	      cp_warning ("`%#T' only defines private constructors and has no friends",
! 			  t);
! 	      return;
! 	    }
! 	}
!     }
  }
  
+ 
  /* Warn about duplicate methods in fn_fields.  Also compact method
     lists so that lookup can be made faster.
  
*************** maybe_class_too_private_p (t)
*** 1945,1960 ****
     We also link each field which has shares a name with its baseclass
     to the head of the list of fields for that base class.  This allows
     us to reduce search time in places like `build_method_call' to
!    consider only reasonably likely functions.  */
  
! tree
! finish_struct_methods (t, fn_fields, nonprivate_method)
       tree t;
-      tree fn_fields;
-      int nonprivate_method;
  {
    tree method_vec;
-   tree save_fn_fields = fn_fields;
    tree ctor_name = constructor_name (t);
    int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
  
--- 2059,2072 ----
     We also link each field which has shares a name with its baseclass
     to the head of the list of fields for that base class.  This allows
     us to reduce search time in places like `build_method_call' to
!    consider only reasonably likely functions.   */
  
! static void
! finish_struct_methods (t)
       tree t;
  {
+   tree fn_fields;
    tree method_vec;
    tree ctor_name = constructor_name (t);
    int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
  
*************** finish_struct_methods (t, fn_fields, non
*** 1972,1979 ****
  
    /* First fill in entry 0 with the constructors, entry 1 with destructors,
       and the next few with type conversion operators (if any).  */
! 
!   for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields))
      {
        tree fn_name = DECL_NAME (fn_fields);
  
--- 2084,2091 ----
  
    /* First fill in entry 0 with the constructors, entry 1 with destructors,
       and the next few with type conversion operators (if any).  */
!   for (fn_fields = TYPE_METHODS (t); fn_fields; 
!        fn_fields = TREE_CHAIN (fn_fields))
      {
        tree fn_name = DECL_NAME (fn_fields);
  
*************** finish_struct_methods (t, fn_fields, non
*** 2021,2028 ****
  	grow_method (fn_fields, &method_vec);
      }
  
!   fn_fields = save_fn_fields;
!   for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields))
      {
        tree fn_name = DECL_NAME (fn_fields);
  
--- 2133,2140 ----
  	grow_method (fn_fields, &method_vec);
      }
  
!   for (fn_fields = TYPE_METHODS (t); fn_fields; 
!        fn_fields = TREE_CHAIN (fn_fields))
      {
        tree fn_name = DECL_NAME (fn_fields);
  
*************** finish_struct_methods (t, fn_fields, non
*** 2050,2082 ****
    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++)
! 	if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i))
! 	    || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i)))
! 	  {
! 	    nonprivate_method = 1;
! 	    break;
! 	  }
!       if (nonprivate_method == 0)
! 	cp_warning ("all member functions in class `%T' are private", t);
!     }
! 
!   /* Warn if all destructors are private (in which case this class is
!      effectively unusable.  */
!   if (TYPE_HAS_DESTRUCTOR (t))
!     {
!       tree dtor = TREE_VEC_ELT (method_vec, 1);
! 
!       /* 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);
!     }
  
    /* Now for each member function (except for constructors and
       destructors), compute where member functions of the same
--- 2162,2175 ----
    obstack_finish (&class_obstack);
    CLASSTYPE_METHOD_VEC (t) = method_vec;
  
!   if (TYPE_HAS_DESTRUCTOR (t) && !TREE_VEC_ELT (method_vec, 1))
!     /* We thought there was a destructor, but there wasn't.  Some
!        parse errors cause this anomalous situation.  */
!     TYPE_HAS_DESTRUCTOR (t) = 0;
!     
!   /* Issue warnings about private constructors and such.  If there are
!      no methods, then some public defaults are generated.  */
!   maybe_warn_about_overly_private_class (t); 
  
    /* Now for each member function (except for constructors and
       destructors), compute where member functions of the same
*************** finish_struct_methods (t, fn_fields, non
*** 2102,2109 ****
        else
  	obstack_free (current_obstack, baselink_vec);
      }
- 
-   return method_vec;
  }
  
  /* Emit error when a duplicate definition of a type is seen.  Patch up.  */
--- 2195,2200 ----
*************** finish_struct_1 (t, warn_anon)
*** 3063,3069 ****
    int any_default_members = 0;
    int const_sans_init = 0;
    int ref_sans_init = 0;
-   int nonprivate_method = 0;
    tree access_decls = NULL_TREE;
    int aggregate = 1;
    int empty = 1;
--- 3154,3159 ----
*************** finish_struct_1 (t, warn_anon)
*** 3165,3172 ****
      {
        GNU_xref_member (current_class_name, x);
  
-       nonprivate_method |= ! TREE_PRIVATE (x);
- 
        /* If this was an evil function, don't keep it in class.  */
        if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x)))
  	continue;
--- 3255,3260 ----
*************** finish_struct_1 (t, warn_anon)
*** 3538,3546 ****
    /* Synthesize any needed methods.  Note that methods will be synthesized
       for anonymous unions; grok_x_components undoes that.  */
  
-   if (! fn_fields)
-     nonprivate_method = 1;
- 
    if (TYPE_NEEDS_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t)
        && !IS_SIGNATURE (t))
      {
--- 3626,3631 ----
*************** finish_struct_1 (t, warn_anon)
*** 3561,3567 ****
  	  if (DECL_VINDEX (dtor))
  	    add_virtual_function (&pending_virtuals, &pending_hard_virtuals,
  				  &has_virtual, dtor, t);
- 	  nonprivate_method = 1;
  	}
      }
  
--- 3646,3651 ----
*************** finish_struct_1 (t, warn_anon)
*** 3632,3659 ****
    if (fn_fields)
      {
        TYPE_METHODS (t) = fn_fields;
!       method_vec = finish_struct_methods (t, fn_fields, nonprivate_method);
! 
!       if (TYPE_HAS_CONSTRUCTOR (t)
! 	  && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
! 	  && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE)
! 	{
! 	  int nonprivate_ctor = 0;
! 	  tree ctor;
! 
! 	  for (ctor = TREE_VEC_ELT (method_vec, 0);
! 	       ctor;
! 	       ctor = OVL_NEXT (ctor))
! 	    if (! TREE_PRIVATE (OVL_CURRENT (ctor)))
! 	      {
! 		nonprivate_ctor = 1;
! 		break;
! 	      }
! 
! 	  if (nonprivate_ctor == 0 && maybe_class_too_private_p (t))
! 	    cp_warning ("`%#T' only defines private constructors and has no friends",
! 			t);
! 	}
      }
    else
      {
--- 3716,3723 ----
    if (fn_fields)
      {
        TYPE_METHODS (t) = fn_fields;
!       finish_struct_methods (t);
!       method_vec = CLASSTYPE_METHOD_VEC (t);
      }
    else
      {
*************** finish_struct (t, list_of_fieldlists, at
*** 4229,4240 ****
  	  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)
  	    {
  	      TREE_PRIVATE (DECL_RESULT (x)) = TREE_PRIVATE (x);
--- 4293,4298 ----
*************** finish_struct (t, list_of_fieldlists, at
*** 4363,4370 ****
  	    = tree_cons (NULL_TREE, d,
  			 DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)));
  	}
!       CLASSTYPE_METHOD_VEC (t)
! 	= finish_struct_methods (t, TYPE_METHODS (t), 1);
        TYPE_SIZE (t) = integer_zero_node;
      }      
    else
--- 4421,4427 ----
  	    = tree_cons (NULL_TREE, d,
  			 DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)));
  	}
!       finish_struct_methods (t);
        TYPE_SIZE (t) = integer_zero_node;
      }      
    else
Index: testsuite/g++.old-deja/g++.benjamin/tem03.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C,v
retrieving revision 1.1
diff -c -p -r1.1 tem03.C
*** tem03.C	1998/08/24 11:57:29	1.1
--- tem03.C	1998/09/15 18:01:54
*************** public:
*** 80,86 ****
  
  // 04
  // local names (14.6.1 p 4)
! template <class T10, int i> class Xfour {// ERROR - .*
    int T10; // ERROR - .*
    void f(){
      char T10; // ERROR - .*
--- 80,86 ----
  
  // 04
  // local names (14.6.1 p 4)
! template <class T10, int i> struct Xfour {// ERROR - .*
    int T10; // ERROR - .*
    void f(){
      char T10; // ERROR - .*
*************** template <class T10, int i> class Xfour 
*** 90,96 ****
  
  // 05
  // using different tempate-parms for out-of-line defs
! template <class T12, int i> class Xfive {
    void f();
  };
  
--- 90,96 ----
  
  // 05
  // using different tempate-parms for out-of-line defs
! template <class T12, int i> struct Xfive {
    void f();
  };
  
*************** public:
*** 189,195 ****
  // 13
  // member templates, non-type parameters
  template <long l>// ERROR - .*
! class Xthirteen {
    template <long l> long comp_ge(long test) {// ERROR - .
      long local_value;
      if (local_value > value) 
--- 189,195 ----
  // 13
  // member templates, non-type parameters
  template <long l>// ERROR - .*
! struct Xthirteen {
    template <long l> long comp_ge(long test) {// ERROR - .
      long local_value;
      if (local_value > value) 
Index: testsuite/g++.old-deja/g++.benjamin/tem04.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.benjamin/tem04.C,v
retrieving revision 1.3
diff -c -p -r1.3 tem04.C
*** tem04.C	1998/09/03 14:29:18	1.3
--- tem04.C	1998/09/15 18:01:54
*************** protected:
*** 112,118 ****
  
  // 20
  // local names (14.6.1 p 4) part two, variable names as template param
! template <class T17, int i> class Xtwenty {
    void f(){
      T17 my_type; //ok
      for (int j = 0; j < 5; ++l)
--- 112,118 ----
  
  // 20
  // local names (14.6.1 p 4) part two, variable names as template param
! template <class T17, int i> struct Xtwenty {
    void f(){
      T17 my_type; //ok
      for (int j = 0; j < 5; ++l)
Index: testsuite/g++.old-deja/g++.jason/tempcons.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.jason/tempcons.C,v
retrieving revision 1.1.1.1
diff -c -p -r1.1.1.1 tempcons.C
*** tempcons.C	1997/08/19 07:35:28	1.1.1.1
--- tempcons.C	1998/09/15 18:01:55
***************
*** 2,8 ****
  // Build don't link:
  
  template <class T>
! class A {
    int i;
    Blarg () : i(0) { }		// ERROR - 
  };
--- 2,8 ----
  // Build don't link:
  
  template <class T>
! struct A {
    int i;
    Blarg () : i(0) { }		// ERROR - 
  };
Index: testsuite/g++.old-deja/g++.pt/memclass8.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.pt/memclass8.C,v
retrieving revision 1.1
diff -c -p -r1.1 memclass8.C
*** memclass8.C	1998/04/26 13:36:02	1.1
--- memclass8.C	1998/09/15 18:01:58
*************** template <class T>
*** 4,10 ****
  class S
  {
    template <class U>
!   class S2 {
      S2(const S2<U>& s2u) {}
    };
  };
--- 4,10 ----
  class S
  {
    template <class U>
!   struct S2 {
      S2(const S2<U>& s2u) {}
    };
  };
Index: testsuite/g++.old-deja/g++.pt/memtemp60.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.pt/memtemp60.C,v
retrieving revision 1.1
diff -c -p -r1.1 memtemp60.C
*** memtemp60.C	1997/09/26 03:13:30	1.1
--- memtemp60.C	1998/09/15 18:01:58
***************
*** 1,7 ****
  // Build don't link:
  // GROUPS passed membertemplates
  template <class T>
! class S
  {
    S(const S<T>& x)  {}
  
--- 1,7 ----
  // Build don't link:
  // GROUPS passed membertemplates
  template <class T>
! struct S
  {
    S(const S<T>& x)  {}
  
Index: testsuite/g++.old-deja/g++.pt/typedef1.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.pt/typedef1.C,v
retrieving revision 1.1
diff -c -p -r1.1 typedef1.C
*** typedef1.C	1997/11/11 06:38:34	1.1
--- typedef1.C	1998/09/15 18:01:58
***************
*** 2,8 ****
  // Build don't link:
  
  template <class T>
! class A
  {
    typedef enum
    {
--- 2,8 ----
  // Build don't link:
  
  template <class T>
! struct A
  {
    typedef enum
    {
Index: testsuite/g++.old-deja/g++.robertl/eb28.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.robertl/eb28.C,v
retrieving revision 1.2
diff -c -p -r1.2 eb28.C
*** eb28.C	1998/05/28 22:44:17	1.2
--- eb28.C	1998/09/15 18:01:58
*************** class a
*** 6,12 ****
          vector<s> vs;
          friend class b;
  };
! class b
  {
          vector<a> va;
          operator vector< vector<s> >()
--- 6,12 ----
          vector<s> vs;
          friend class b;
  };
! struct b
  {
          vector<a> va;
          operator vector< vector<s> >()
Index: testsuite/g++.old-deja/g++.robertl/eb29.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.robertl/eb29.C,v
retrieving revision 1.2
diff -c -p -r1.2 eb29.C
*** eb29.C	1998/05/28 22:44:18	1.2
--- eb29.C	1998/09/15 18:01:58
*************** class a
*** 6,12 ****
          vector<s> vs;
          friend class b;
  };
! class b
  {
          vector<a> va;
          operator vector< vector<s> >()
--- 6,12 ----
          vector<s> vs;
          friend class b;
  };
! struct b
  {
          vector<a> va;
          operator vector< vector<s> >()
Index: testsuite/g++.old-deja/g++.other/warn3.C
===================================================================
RCS file: warn3.C
diff -N warn3.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- warn3.C	Tue Sep 15 11:31:43 1998
***************
*** 0 ****
--- 1,54 ----
+ // Build don't link:
+ 
+ class A {
+ };
+ 
+ 
+ class B {
+ public:
+   void f();
+ 
+ private:
+   B (); 
+   B (const B&);
+ }; // WARNING - only private constructors
+ 
+ 
+ class C { 
+ public: 
+   void f();
+ 
+ private:
+   ~C (); 
+ }; // WARNING - only private destructors
+ 
+ 
+ class D {
+ private:
+   void f(); 
+ }; // WARNING - all member functions are private
+ 
+ 
+ template <class T>
+ class X {
+ private:
+   ~X (); 
+ }; // WARNING - only private destructors
+ 
+ template class X<int>;
+ template class X<double>;
+ 
+ 
+ template <class T>
+ class Y {
+ private:
+   Y (); 
+   Y (const Y&);
+ }; // WARNING - only private constructors
+ 
+ 
+ template <class T>
+ class Z {
+ private:
+   void f(); 
+ }; // WARNING - all member functions are private



More information about the Gcc-patches mailing list