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> 2009-11-19 Jason Merrill <jason@redhat.com>
PR c++/42115 PR c++/42115
......
...@@ -3977,7 +3977,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, ...@@ -3977,7 +3977,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
|| (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type))) || (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type)))
{ {
result_type = composite_pointer_type (arg2_type, arg3_type, arg2, result_type = composite_pointer_type (arg2_type, arg3_type, arg2,
arg3, "conditional expression", arg3, CPO_CONDITIONAL_EXPR,
complain); complain);
if (result_type == error_mark_node) if (result_type == error_mark_node)
return error_mark_node; return error_mark_node;
......
...@@ -403,6 +403,17 @@ typedef enum cpp0x_warn_str ...@@ -403,6 +403,17 @@ typedef enum cpp0x_warn_str
CPP0X_DEFAULTED_DELETED CPP0X_DEFAULTED_DELETED
} cpp0x_warn_str; } 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. */ /* Macros for access to language-specific slots in an identifier. */
...@@ -5281,7 +5292,8 @@ extern void expand_ptrmemfunc_cst (tree, tree *, tree *); ...@@ -5281,7 +5292,8 @@ extern void expand_ptrmemfunc_cst (tree, tree *, tree *);
extern tree type_after_usual_arithmetic_conversions (tree, tree); extern tree type_after_usual_arithmetic_conversions (tree, tree);
extern tree common_pointer_type (tree, tree); extern tree common_pointer_type (tree, tree);
extern tree composite_pointer_type (tree, tree, 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 merge_types (tree, tree);
extern tree check_return_expr (tree, bool *); extern tree check_return_expr (tree, bool *);
extern tree cp_build_binary_op (location_t, extern tree cp_build_binary_op (location_t,
......
...@@ -421,10 +421,11 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2) ...@@ -421,10 +421,11 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2)
} }
/* Subroutine of composite_pointer_type to implement the recursive /* 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 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) tsubst_flags_t complain)
{ {
tree pointee1; tree pointee1;
...@@ -457,14 +458,33 @@ composite_pointer_type_r (tree t1, tree t2, const char* location, ...@@ -457,14 +458,33 @@ composite_pointer_type_r (tree t1, tree t2, const char* location,
&& TREE_CODE (pointee2) == POINTER_TYPE) && TREE_CODE (pointee2) == POINTER_TYPE)
|| (TYPE_PTR_TO_MEMBER_P (pointee1) || (TYPE_PTR_TO_MEMBER_P (pointee1)
&& TYPE_PTR_TO_MEMBER_P (pointee2))) && 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); complain);
else else
{ {
if (complain & tf_error) if (complain & tf_error)
permerror (input_location, "%s between distinct pointer types %qT and %qT " {
"lacks a cast", switch (operation)
location, t1, t2); {
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 = void_type_node;
} }
result_type = cp_build_qualified_type (result_type, result_type = cp_build_qualified_type (result_type,
...@@ -477,9 +497,28 @@ composite_pointer_type_r (tree t1, tree t2, const char* location, ...@@ -477,9 +497,28 @@ composite_pointer_type_r (tree t1, tree t2, const char* location,
if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1), if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
TYPE_PTRMEM_CLASS_TYPE (t2)) TYPE_PTRMEM_CLASS_TYPE (t2))
&& (complain & tf_error)) && (complain & tf_error))
permerror (input_location, "%s between distinct pointer types %qT and %qT " {
"lacks a cast", switch (operation)
location, t1, t2); {
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 = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
result_type); result_type);
} }
...@@ -492,15 +531,17 @@ composite_pointer_type_r (tree t1, tree t2, const char* location, ...@@ -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. /* 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 ARG1 and ARG2 are the values with those types. The OPERATION is to
string describing the current location, in case an error occurs. describe the operation between the pointer types,
in case an error occurs.
This routine also implements the computation of a common type for This routine also implements the computation of a common type for
pointers-to-members as per [expr.eq]. */ pointers-to-members as per [expr.eq]. */
tree tree
composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2, 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 class1;
tree class2; tree class2;
...@@ -539,9 +580,28 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2, ...@@ -539,9 +580,28 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
tree result_type; tree result_type;
if (TYPE_PTRFN_P (t2) && (complain & tf_error)) 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", switch (operation)
location); {
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 result_type
= cp_build_qualified_type (void_type_node, = cp_build_qualified_type (void_type_node,
(cp_type_quals (TREE_TYPE (t1)) (cp_type_quals (TREE_TYPE (t1))
...@@ -579,8 +639,23 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2, ...@@ -579,8 +639,23 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
else else
{ {
if (complain & tf_error) if (complain & tf_error)
error ("%s between distinct pointer types %qT and %qT " switch (operation)
"lacks a cast", location, t1, t2); {
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; return error_mark_node;
} }
} }
...@@ -600,13 +675,31 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2, ...@@ -600,13 +675,31 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
else else
{ {
if (complain & tf_error) if (complain & tf_error)
error ("%s between distinct pointer-to-member types %qT and %qT " switch (operation)
"lacks a cast", location, t1, t2); {
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 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. /* Return the merged type of two types.
...@@ -820,7 +913,7 @@ common_pointer_type (tree t1, tree t2) ...@@ -820,7 +913,7 @@ common_pointer_type (tree t1, tree t2)
|| (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2))); || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)));
return composite_pointer_type (t1, t2, error_mark_node, error_mark_node, 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 /* Compare two exception specifier types for exactness or subsetness, if
...@@ -3683,7 +3776,7 @@ cp_build_binary_op (location_t location, ...@@ -3683,7 +3776,7 @@ cp_build_binary_op (location_t location,
else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE) else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
|| (TYPE_PTRMEM_P (type0) && TYPE_PTRMEM_P (type1))) || (TYPE_PTRMEM_P (type0) && TYPE_PTRMEM_P (type1)))
result_type = composite_pointer_type (type0, type1, op0, op1, result_type = composite_pointer_type (type0, type1, op0, op1,
"comparison", complain); CPO_COMPARISON, complain);
else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0)) else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0))
&& null_ptr_cst_p (op1)) && null_ptr_cst_p (op1))
{ {
...@@ -3772,8 +3865,8 @@ cp_build_binary_op (location_t location, ...@@ -3772,8 +3865,8 @@ cp_build_binary_op (location_t location,
tree delta0; tree delta0;
tree delta1; tree delta1;
type = composite_pointer_type (type0, type1, op0, op1, "comparison", type = composite_pointer_type (type0, type1, op0, op1,
complain); CPO_COMPARISON, complain);
if (!same_type_p (TREE_TYPE (op0), type)) if (!same_type_p (TREE_TYPE (op0), type))
op0 = cp_convert_and_check (type, op0); op0 = cp_convert_and_check (type, op0);
...@@ -3884,7 +3977,7 @@ cp_build_binary_op (location_t location, ...@@ -3884,7 +3977,7 @@ cp_build_binary_op (location_t location,
shorten = 1; shorten = 1;
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
result_type = composite_pointer_type (type0, type1, op0, op1, result_type = composite_pointer_type (type0, type1, op0, op1,
"comparison", complain); CPO_COMPARISON, complain);
break; break;
case LE_EXPR: case LE_EXPR:
...@@ -3904,7 +3997,7 @@ cp_build_binary_op (location_t location, ...@@ -3904,7 +3997,7 @@ cp_build_binary_op (location_t location,
short_compare = 1; short_compare = 1;
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
result_type = composite_pointer_type (type0, type1, op0, op1, result_type = composite_pointer_type (type0, type1, op0, op1,
"comparison", complain); CPO_COMPARISON, complain);
else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
&& integer_zerop (op1)) && integer_zerop (op1))
result_type = type0; 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> 2009-11-20 Paul Thomas <pault@gcc.gnu.org>
Janus Weil <janus@gcc.gnu.org> Janus Weil <janus@gcc.gnu.org>
......
...@@ -22,5 +22,5 @@ void f () ...@@ -22,5 +22,5 @@ void f ()
pd == pb; pd == pb;
pd == pbv; // { dg-error "" } 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 { ...@@ -8,5 +8,5 @@ struct IsZero : Term {
Term* Term*
IsZero::eval() 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); ...@@ -13,7 +13,7 @@ void (*fp)(void);
void function_1 () 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; } int main () { return 0; }
...@@ -6,5 +6,5 @@ void *vp; ...@@ -6,5 +6,5 @@ void *vp;
void example () 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 @@ ...@@ -13,6 +13,6 @@
int test( const foo* f, const bar* b ) 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]; ...@@ -9,6 +9,6 @@ int (*p2)[5];
void void
test () test ()
{ {
p1 == p2; // { dg-error "" } comparison.* p1 == p2; // { dg-error "comparison between distinct pointer types" } comparison.*
p1 > p2; // { dg-error "" } comparison.* p1 > p2; // { dg-error "comparison between distinct pointer types" } comparison.*
} }
...@@ -12,5 +12,5 @@ int i; ...@@ -12,5 +12,5 @@ int i;
void void
test () 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