[C++ PATCH]: Fix ptr to member syntax checking

Nathan Sidwell nathan@codesourcery.com
Tue Sep 5 03:04:00 GMT 2000


Jason Merrill wrote:
> 
> It seems to me that this makes the error message much less helpful.  Please
> continue to use use the error message from instantiate_type,
> 
> -           cp_pedwarn
> -             ("object-dependent reference to `%E' can only be used in a call",
> -              DECL_NAME (fn));

That original message is not quite appropriate anymore, as the
diagnostic is now issued on the non-object dependent references 
`T::m' and `&(T::m)', which looks stunningly like a pointers to member,
but are explicitly disallowed by [5.3.1]/3

How about the attached patch, which issues a one-time explanation? It
also tidies up the other places where such one-time explanations are
issued. (I renamed the static variable to `explained' in each place
to make them easier to find in future.)

ok?

nathan
-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-09-05  Nathan Sidwell  <nathan@codesourcery.com>

	* class.c (resolve_address_of_overloaded_function): Add
	explanation message.
	* decl.c (define_case_label): Reformat explanation.
	* decl2.c (finish_static_data_member_decl): Likewise.
	(grokfield): Likewise.
	* friend.c (do_friend): Likewise.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.335
diff -c -3 -p -r1.335 class.c
*** class.c	2000/09/05 00:57:55	1.335
--- class.c	2000/09/05 09:31:24
*************** resolve_address_of_overloaded_function (
*** 5965,5977 ****
    /* Good, exactly one match.  Now, convert it to the correct type.  */
    fn = TREE_PURPOSE (matches);
  
!   if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
        && !ptrmem && !flag_ms_extensions)
      {
        if (!complain)
          return error_mark_node;
  
        cp_pedwarn ("assuming pointer to member `%D'", fn);
      }
    mark_used (fn);
  
--- 5965,5984 ----
    /* Good, exactly one match.  Now, convert it to the correct type.  */
    fn = TREE_PURPOSE (matches);
  
!   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
        && !ptrmem && !flag_ms_extensions)
      {
+       static int explained;
+       
        if (!complain)
          return error_mark_node;
  
        cp_pedwarn ("assuming pointer to member `%D'", fn);
+       if (!explained)
+         {
+           cp_pedwarn ("(a pointer to member can only be formed with `&%E')", fn);
+           explained = 1;
+         }
      }
    mark_used (fn);
  
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.681
diff -c -3 -p -r1.681 decl.c
*** decl.c	2000/09/05 07:31:26	1.681
--- decl.c	2000/09/05 09:31:31
*************** define_case_label ()
*** 5227,5234 ****
        warning ("where case label appears here");
        if (!explained)
  	{
! 	  warning ("(enclose actions of previous case statements requiring");
! 	  warning ("destructors in their own binding contours.)");
  	  explained = 1;
  	}
      }
--- 5227,5233 ----
        warning ("where case label appears here");
        if (!explained)
  	{
! 	  warning ("(enclose actions of previous case statements requiring destructors in their own binding contours.)");
  	  explained = 1;
  	}
      }
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.392
diff -c -3 -p -r1.392 decl2.c
*** decl2.c	2000/09/05 00:57:56	1.392
--- decl2.c	2000/09/05 09:31:33
*************** finish_static_data_member_decl (decl, in
*** 1597,1608 ****
    /* Static consts need not be initialized in the class definition.  */
    if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
      {
!       static int explanation = 0;
  	  
        error ("initializer invalid for static member with constructor");
!       if (explanation++ == 0)
! 	error ("(you really want to initialize it separately)");
!       init = 0;
      }
    /* Force the compiler to know when an uninitialized static const
       member is being used.  */
--- 1597,1611 ----
    /* Static consts need not be initialized in the class definition.  */
    if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
      {
!       static int explained = 0;
  	  
        error ("initializer invalid for static member with constructor");
!       if (!explained)
!         {
! 	  error ("(an out of class initialization is required)");
! 	  explained = 1;
! 	}
!       init = NULL_TREE;
      }
    /* Force the compiler to know when an uninitialized static const
       member is being used.  */
*************** grokfield (declarator, declspecs, init, 
*** 1656,1668 ****
  	    };
  	    
  	 Explain that to the user.  */
!       static int explained_p;
  
        cp_error ("invalid data member initiailization");
!       if (!explained_p)
  	{
! 	  cp_error ("use `=' to initialize static data members");
! 	  explained_p = 1;
  	}
  
        declarator = TREE_OPERAND (declarator, 0);
--- 1659,1671 ----
  	    };
  	    
  	 Explain that to the user.  */
!       static int explained;
  
        cp_error ("invalid data member initiailization");
!       if (!explained)
  	{
! 	  cp_error ("(use `=' to initialize static data members)");
! 	  explained = 1;
  	}
  
        declarator = TREE_OPERAND (declarator, 0);
Index: cp/friend.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/friend.c,v
retrieving revision 1.60
diff -c -3 -p -r1.60 friend.c
*** friend.c	2000/08/18 10:49:17	1.60
--- friend.c	2000/09/05 09:31:33
*************** do_friend (ctype, declarator, decl, parm
*** 399,409 ****
  	      && current_template_parms && uses_template_parms (decl))
  	    {
  	      static int explained;
! 	      cp_warning ("friend declaration `%#D'", decl);
! 	      warning ("  declares a non-template function");
  	      if (! explained)
  		{
! 		  warning ("  (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning.");
  		  explained = 1;
  		}
  	    }
--- 399,408 ----
  	      && current_template_parms && uses_template_parms (decl))
  	    {
  	      static int explained;
! 	      cp_warning ("friend declaration `%#D' declares a non-template function", decl);
  	      if (! explained)
  		{
! 		  warning ("(if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning.");
  		  explained = 1;
  		}
  	    }


More information about the Gcc-patches mailing list