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
This commit is contained in:
Shujing Zhao 2009-11-20 10:05:37 +00:00 committed by Paolo Carlini
parent 3de8a540d8
commit c86818cfbe
12 changed files with 174 additions and 45 deletions

View File

@ -1,3 +1,16 @@
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

View File

@ -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;

View File

@ -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,

View File

@ -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))
@ -577,17 +637,32 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
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, tree arg1, tree arg2,
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;

View File

@ -1,3 +1,14 @@
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>

View File

@ -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" }
}

View File

@ -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" }
}

View File

@ -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; }

View File

@ -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*
}

View File

@ -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" }
}

View File

@ -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.*
}

View File

@ -12,5 +12,5 @@ int i;
void
test ()
{
i ? f : fp; // { dg-error "" }
i ? f : fp; // { dg-error "conditional expression|invalid conversion" }
}