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]

Re: [PATCH, PR c++/29017] Fix composite_pointer_type i18n problems


On 11/20/2009 05:17 PM, Gabriel Dos Reis wrote:
On Fri, Nov 20, 2009 at 2:11 AM, Shujing Zhao <pearly.zhao@oracle.com> wrote:
On 11/20/2009 11:12 AM, Joseph S. Myers wrote:
On Fri, 20 Nov 2009, Shujing Zhao wrote:

Hi,

This patch is to adjust the function composite_pointer_type to make the
diagnostic messages be easy translation. It is also be passed by an enum
to
transfer the message information.
Some test cases are changed to make the expected dg-error strings
explicit.
It is tested on i686-pc-linux-gnu and the diagnostic sentences can be
extracted to gcc.pot by execute "make gcc.pot" at objdir/gcc.
It is ok for trunk?
By creating a function returning diagnostic strings, you are losing the
compile-time format checking on those strings.  It would be better to place
the switch statements at the call sites, with each switch containing a call
to a diagnostic function in each case.  Or you could use a macro like
c-typeck.c:WARN_FOR_ASSIGNMENT if there are many places with a switch over
the same enum, calling the same diagnostic function.

Thanks. Update the patch to place the switch statements at the call sites.
WARN_FOR_ASSIGNMENT is a good example, but this issue calls different
diagnostic functions.
Is it ok?

Change


   enum cmp_ptr_type_op
   {
       // ...
   };

to

   typedef  enum composite_pointer_operation
   {
      // ..
   } composite_pointer_operation;

and use the typedef name in the function signatures
as opposed to the 'enum ...' specifier.

Patch OK with that change.
Thanks. Update the patch and ChangeLog for commit.
Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 154358)
+++ cp/typeck.c	(working copy)
@@ -421,10 +421,11 @@ type_after_usual_arithmetic_conversions 
 }
 
 /* Subroutine of composite_pointer_type to implement the recursive
-   case.  See that function for documentation fo the parameters.  */
+   case.  See that function for documentation of the parameters.  */
 
 static tree
-composite_pointer_type_r (tree t1, tree t2, const char* location,
+composite_pointer_type_r (tree t1, tree t2, 
+			  composite_pointer_operation operation,
 			  tsubst_flags_t complain)
 {
   tree pointee1;
@@ -457,14 +458,33 @@ composite_pointer_type_r (tree t1, tree 
 	    && TREE_CODE (pointee2) == POINTER_TYPE)
 	   || (TYPE_PTR_TO_MEMBER_P (pointee1)
 	       && TYPE_PTR_TO_MEMBER_P (pointee2)))
-    result_type = composite_pointer_type_r (pointee1, pointee2, location,
+    result_type = composite_pointer_type_r (pointee1, pointee2, operation,
 					    complain);
   else
     {
       if (complain & tf_error)
-	permerror (input_location, "%s between distinct pointer types %qT and %qT "
-		   "lacks a cast",
-		   location, t1, t2);
+        {
+          switch (operation)
+            {
+            case CPO_COMPARISON:
+              permerror (input_location, "comparison between "
+                         "distinct pointer types %qT and %qT lacks a cast",
+                         t1, t2);
+              break;
+            case CPO_CONVERSION:
+              permerror (input_location, "conversion between "
+                         "distinct pointer types %qT and %qT lacks a cast",
+                         t1, t2);
+              break;
+            case CPO_CONDITIONAL_EXPR:
+              permerror (input_location, "conditional expression between "
+                         "distinct pointer types %qT and %qT lacks a cast",
+                         t1, t2);
+              break;
+            default:
+              gcc_unreachable ();
+            }
+        }
       result_type = void_type_node;
     }
   result_type = cp_build_qualified_type (result_type,
@@ -477,9 +497,28 @@ composite_pointer_type_r (tree t1, tree 
       if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
 			TYPE_PTRMEM_CLASS_TYPE (t2))
 	  && (complain & tf_error))
-	permerror (input_location, "%s between distinct pointer types %qT and %qT "
-		   "lacks a cast",
-		   location, t1, t2);
+        {
+          switch (operation)
+            {
+            case CPO_COMPARISON:
+              permerror (input_location, "comparison between "
+                         "distinct pointer types %qT and %qT lacks a cast", 
+                         t1, t2);
+              break;
+            case CPO_CONVERSION:
+              permerror (input_location, "conversion between "
+                         "distinct pointer types %qT and %qT lacks a cast",
+                         t1, t2);
+              break;
+            case CPO_CONDITIONAL_EXPR:
+              permerror (input_location, "conditional expression between "
+                         "distinct pointer types %qT and %qT lacks a cast",
+                         t1, t2);
+              break;
+            default:
+              gcc_unreachable ();
+            }
+        }
       result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
 				       result_type);
     }
@@ -492,15 +531,17 @@ composite_pointer_type_r (tree t1, tree 
 }
 
 /* Return the composite pointer type (see [expr.rel]) for T1 and T2.
-   ARG1 and ARG2 are the values with those types.  The LOCATION is a
-   string describing the current location, in case an error occurs.
+   ARG1 and ARG2 are the values with those types.  The OPERATION is to
+   describe the operation between the pointer types,
+   in case an error occurs.
 
    This routine also implements the computation of a common type for
    pointers-to-members as per [expr.eq].  */
 
 tree
 composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
-			const char* location, tsubst_flags_t complain)
+			composite_pointer_operation operation, 
+			tsubst_flags_t complain)
 {
   tree class1;
   tree class2;
@@ -539,9 +580,28 @@ composite_pointer_type (tree t1, tree t2
       tree result_type;
 
       if (TYPE_PTRFN_P (t2) && (complain & tf_error))
-	pedwarn (input_location, OPT_pedantic, "ISO C++ forbids %s "
-		 "between pointer of type %<void *%> and pointer-to-function",
-		 location);
+        {
+          switch (operation)
+              {
+              case CPO_COMPARISON:
+                pedwarn (input_location, OPT_pedantic, 
+                         "ISO C++ forbids comparison between "
+                         "pointer of type %<void *%> and pointer-to-function");
+                break;
+              case CPO_CONVERSION:
+                pedwarn (input_location, OPT_pedantic,
+                         "ISO C++ forbids conversion between "
+                         "pointer of type %<void *%> and pointer-to-function");
+                break;
+              case CPO_CONDITIONAL_EXPR:
+                pedwarn (input_location, OPT_pedantic,
+                         "ISO C++ forbids conditional expression between "
+                         "pointer of type %<void *%> and pointer-to-function");
+                break;
+              default:
+                gcc_unreachable ();
+              }
+        }
       result_type
 	= cp_build_qualified_type (void_type_node,
 				   (cp_type_quals (TREE_TYPE (t1))
@@ -577,17 +637,32 @@ composite_pointer_type (tree t1, tree t2
 	t1 = (build_pointer_type
 	      (cp_build_qualified_type (class2, TYPE_QUALS (class1))));
       else
-	{
-	  if (complain & tf_error)
-	    error ("%s between distinct pointer types %qT and %qT "
-		   "lacks a cast", location, t1, t2);
-	  return error_mark_node;
-	}
+        {
+          if (complain & tf_error)
+            switch (operation)
+              {
+              case CPO_COMPARISON:
+                error ("comparison between distinct "
+                       "pointer types %qT and %qT lacks a cast", t1, t2);
+                break;
+              case CPO_CONVERSION:
+                error ("conversion between distinct "
+                       "pointer types %qT and %qT lacks a cast", t1, t2);
+                break;
+              case CPO_CONDITIONAL_EXPR:
+                error ("conditional expression between distinct "
+                       "pointer types %qT and %qT lacks a cast", t1, t2);
+                break;
+              default:
+                gcc_unreachable ();
+              }
+          return error_mark_node;
+        }
     }
   /* [expr.eq] permits the application of a pointer-to-member
      conversion to change the class type of one of the types.  */
   else if (TYPE_PTR_TO_MEMBER_P (t1)
-	   && !same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
+           && !same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
 			    TYPE_PTRMEM_CLASS_TYPE (t2)))
     {
       class1 = TYPE_PTRMEM_CLASS_TYPE (t1);
@@ -598,15 +673,33 @@ composite_pointer_type (tree t1, tree t2
       else if (DERIVED_FROM_P (class2, class1))
 	t2 = build_ptrmem_type (class1, TYPE_PTRMEM_POINTED_TO_TYPE (t2));
       else
-	{
-	  if (complain & tf_error)
-	    error ("%s between distinct pointer-to-member types %qT and %qT "
-		   "lacks a cast", location, t1, t2);
-	  return error_mark_node;
-	}
+        {
+          if (complain & tf_error)
+            switch (operation)
+              {
+              case CPO_COMPARISON:
+                error ("comparison between distinct "
+                       "pointer-to-member types %qT and %qT lacks a cast",
+                       t1, t2);
+                break;
+              case CPO_CONVERSION:
+                error ("conversion between distinct "
+                       "pointer-to-member types %qT and %qT lacks a cast",
+                       t1, t2);
+                break;
+              case CPO_CONDITIONAL_EXPR:
+                error ("conditional expression between distinct "
+                       "pointer-to-member types %qT and %qT lacks a cast",
+                       t1, t2);
+                break;
+              default:
+                gcc_unreachable ();
+              }
+          return error_mark_node;
+        }
     }
 
-  return composite_pointer_type_r (t1, t2, location, complain);
+  return composite_pointer_type_r (t1, t2, operation, complain);
 }
 
 /* Return the merged type of two types.
@@ -820,7 +913,7 @@ common_pointer_type (tree t1, tree t2)
               || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)));
 
   return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
-                                 "conversion", tf_warning_or_error);
+                                 CPO_CONVERSION, tf_warning_or_error);
 }
 
 /* Compare two exception specifier types for exactness or subsetness, if
@@ -3683,7 +3776,7 @@ cp_build_binary_op (location_t location,
       else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
 	       || (TYPE_PTRMEM_P (type0) && TYPE_PTRMEM_P (type1)))
 	result_type = composite_pointer_type (type0, type1, op0, op1,
-					      "comparison", complain);
+					      CPO_COMPARISON, complain);
       else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0))
 	       && null_ptr_cst_p (op1))
 	{
@@ -3772,8 +3865,8 @@ cp_build_binary_op (location_t location,
 	  tree delta0;
 	  tree delta1;
 
-	  type = composite_pointer_type (type0, type1, op0, op1, "comparison",
-					 complain);
+	  type = composite_pointer_type (type0, type1, op0, op1, 
+					 CPO_COMPARISON, complain);
 
 	  if (!same_type_p (TREE_TYPE (op0), type))
 	    op0 = cp_convert_and_check (type, op0);
@@ -3884,7 +3977,7 @@ cp_build_binary_op (location_t location,
 	shorten = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
 	result_type = composite_pointer_type (type0, type1, op0, op1,
-					      "comparison", complain);
+					      CPO_COMPARISON, complain);
       break;
 
     case LE_EXPR:
@@ -3904,7 +3997,7 @@ cp_build_binary_op (location_t location,
 	short_compare = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
 	result_type = composite_pointer_type (type0, type1, op0, op1,
-					      "comparison", complain);
+					      CPO_COMPARISON, complain);
       else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
 	       && integer_zerop (op1))
 	result_type = type0;
Index: cp/call.c
===================================================================
--- cp/call.c	(revision 154353)
+++ cp/call.c	(working copy)
@@ -3977,7 +3977,7 @@ build_conditional_expr (tree arg1, tree 
 	   || (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type)))
     {
       result_type = composite_pointer_type (arg2_type, arg3_type, arg2,
-					    arg3, "conditional expression",
+					    arg3, CPO_CONDITIONAL_EXPR,
 					    complain);
       if (result_type == error_mark_node)
 	return error_mark_node;
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 154353)
+++ cp/cp-tree.h	(working copy)
@@ -403,6 +403,17 @@ typedef enum cpp0x_warn_str
   CPP0X_DEFAULTED_DELETED
 } cpp0x_warn_str;
   
+/* The various kinds of operation used by composite_pointer_type. */
+
+typedef enum composite_pointer_operation
+{
+  /* comparison */
+  CPO_COMPARISON,
+  /* conversion */
+  CPO_CONVERSION,
+  /* conditional expression */
+  CPO_CONDITIONAL_EXPR
+} composite_pointer_operation;
 
 /* Macros for access to language-specific slots in an identifier.  */
 
@@ -5281,7 +5292,8 @@ extern void expand_ptrmemfunc_cst		(tree
 extern tree type_after_usual_arithmetic_conversions (tree, tree);
 extern tree common_pointer_type                 (tree, tree);
 extern tree composite_pointer_type		(tree, tree, tree, tree,
-						 const char*, tsubst_flags_t);
+						 composite_pointer_operation, 
+						 tsubst_flags_t);
 extern tree merge_types				(tree, tree);
 extern tree check_return_expr			(tree, bool *);
 extern tree cp_build_binary_op                  (location_t,
Index: testsuite/g++.old-deja/g++.jason/rfg20.C
===================================================================
--- testsuite/g++.old-deja/g++.jason/rfg20.C	(revision 154324)
+++ testsuite/g++.old-deja/g++.jason/rfg20.C	(working copy)
@@ -6,5 +6,5 @@ void *vp;
 
 void example ()
 {
-    vp != fp;			// { dg-error "" } no conversion from pfn to void*
+    vp != fp;			// { dg-error "forbids comparison" } no conversion from pfn to void*
 }
Index: testsuite/g++.old-deja/g++.rfg/00321_01-.C
===================================================================
--- testsuite/g++.old-deja/g++.rfg/00321_01-.C	(revision 154324)
+++ testsuite/g++.old-deja/g++.rfg/00321_01-.C	(working copy)
@@ -9,6 +9,6 @@ int (*p2)[5];
 void
 test ()
 {
-  p1 == p2;		// { dg-error "" } comparison.*
-  p1 > p2;		// { dg-error "" } comparison.*
+  p1 == p2;		// { dg-error "comparison between distinct pointer types" } comparison.*
+  p1 > p2;		// { dg-error "comparison between distinct pointer types" } comparison.*
 }
Index: testsuite/g++.old-deja/g++.rfg/00324_02-.C
===================================================================
--- testsuite/g++.old-deja/g++.rfg/00324_02-.C	(revision 154324)
+++ testsuite/g++.old-deja/g++.rfg/00324_02-.C	(working copy)
@@ -12,5 +12,5 @@ int i;
 void
 test ()
 {
-   i ? f : fp; // { dg-error "" } 
+   i ? f : fp; // { dg-error "conditional expression|invalid conversion" } 
 }
Index: testsuite/g++.old-deja/g++.law/typeck1.C
===================================================================
--- testsuite/g++.old-deja/g++.law/typeck1.C	(revision 154324)
+++ testsuite/g++.old-deja/g++.law/typeck1.C	(working copy)
@@ -13,6 +13,6 @@
 
         int test( const foo* f, const bar* b )
                 {
-                return f == b;// { dg-error "" } 
+                return f == b;// { dg-error "comparison between distinct pointer types" } 
                 }
 
Index: testsuite/g++.old-deja/g++.bugs/900324_02.C
===================================================================
--- testsuite/g++.old-deja/g++.bugs/900324_02.C	(revision 154324)
+++ testsuite/g++.old-deja/g++.bugs/900324_02.C	(working copy)
@@ -13,7 +13,7 @@ void (*fp)(void);
 
 void function_1 ()
 {
-  fp = 1 ? function_0 : fp;		// { dg-error "" } 
+  fp = 1 ? function_0 : fp;		// { dg-error "conditional expression|invalid conversion" } 
 }
 
 int main () { return 0; }
Index: testsuite/g++.dg/conversion/ptrmem9.C
===================================================================
--- testsuite/g++.dg/conversion/ptrmem9.C	(revision 154324)
+++ testsuite/g++.dg/conversion/ptrmem9.C	(working copy)
@@ -22,5 +22,5 @@ void f ()
 
   pd == pb;
   pd == pbv;  // { dg-error "" }
-  pd == pc;   // { dg-error "" }
+  pd == pc;   // { dg-error "comparison between distinct pointer-to-member types" }
 }
Index: testsuite/g++.dg/expr/cond2.C
===================================================================
--- testsuite/g++.dg/expr/cond2.C	(revision 154324)
+++ testsuite/g++.dg/expr/cond2.C	(working copy)
@@ -8,5 +8,5 @@ struct IsZero : Term {
 Term*
 IsZero::eval()
 {
-  return true ? new Boolean(false) : this; // { dg-error "" }
+  return true ? new Boolean(false) : this; // { dg-error "conditional expression" }
 }
2009-11-20  Shujing Zhao  <pearly.zhao@oracle.com>

	PR c++/29017
	* cp-tree.h (composite_pointer_operation): New type.
	(composite_pointer_type): Adjust prototype with new argument.
	* typeck.c (composite_pointer_type): Accept 
	composite_pointer_operation as argument and emit diagnostic to be 
	visible to gettext and checked at compile time.
	(composite_pointer_type_r): Likewise.
	(common_pointer_type): Update call to composite_pointer_type.
	(cp_build_binary_op): Likewise.
	* call.c (build_conditional_expr): Likewise.

2009-11-20  Shujing Zhao  <pearly.zhao@oracle.com>

	* g++.old-deja/g++.jason/rfg20.C: Make expected dg-error strings
	explicit.
	* g++.old-deja/g++.rfg/00321_01-.C: Likewise.
	* g++.old-deja/g++.rfg/00324_02-.C: Likewise.
	* g++.old-deja/g++.law/typeck1.C: Likewise.
	* g++.old-deja/g++.bugs/900324_02.C: Likewise.
	* g++.dg/conversion/ptrmem9.C: Likewise.
	* g++.dg/expr/cond2.C: Likewise.


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