Commit c86818cf by Shujing Zhao Committed by Paolo Carlini

re PR c++/29017 (%s substituted with different untranslated words can't be properly translated)

/cp
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.

/testsuite
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.

From-SVN: r154360
parent 3de8a540
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-19 Jason Merrill <jason@redhat.com>
PR c++/42115
......
......@@ -3977,7 +3977,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
|| (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;
......
......@@ -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, tree *, 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,
......
......@@ -421,10 +421,11 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2)
}
/* 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 t2, const char* location,
&& 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 t2, const char* location,
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 t2, const char* location,
}
/* 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 arg1, tree arg2,
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))
......@@ -579,8 +639,23 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
else
{
if (complain & tf_error)
error ("%s between distinct pointer types %qT and %qT "
"lacks a cast", location, t1, t2);
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;
}
}
......@@ -600,13 +675,31 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
else
{
if (complain & tf_error)
error ("%s between distinct pointer-to-member types %qT and %qT "
"lacks a cast", location, t1, t2);
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;
......
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.
2009-11-20 Paul Thomas <pault@gcc.gnu.org>
Janus Weil <janus@gcc.gnu.org>
......
......@@ -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" }
}
......@@ -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" }
}
......@@ -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; }
......@@ -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*
}
......@@ -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" }
}
......@@ -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.*
}
......@@ -12,5 +12,5 @@ int i;
void
test ()
{
i ? f : fp; // { dg-error "" }
i ? f : fp; // { dg-error "conditional expression|invalid conversion" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment