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:
parent
3de8a540d8
commit
c86818cfbe
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
163
gcc/cp/typeck.c
163
gcc/cp/typeck.c
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue