This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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.