From: paolo Date: Fri, 20 Nov 2009 10:05:37 +0000 (+0000) Subject: /cp X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=2f182218f86be69c5a107780410b2c303c1539f2 /cp 2009-11-20 Shujing Zhao 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 * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154360 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 042e637f8ea..b5b2b04fe1d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2009-11-20 Shujing Zhao + + 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 PR c++/42115 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 3b3ccb66bad..b4c8176c626 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index cae259b6b36..88387705a1b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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, diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 4c02f78f2b1..8685530a4dd 100644 --- a/gcc/cp/typeck.c +++ b/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 % and pointer-to-function", - location); + { + switch (operation) + { + case CPO_COMPARISON: + pedwarn (input_location, OPT_pedantic, + "ISO C++ forbids comparison between " + "pointer of type % and pointer-to-function"); + break; + case CPO_CONVERSION: + pedwarn (input_location, OPT_pedantic, + "ISO C++ forbids conversion between " + "pointer of type % and pointer-to-function"); + break; + case CPO_CONDITIONAL_EXPR: + pedwarn (input_location, OPT_pedantic, + "ISO C++ forbids conditional expression between " + "pointer of type % 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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fdc14b95b5d..56b217cbe53 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2009-11-20 Shujing Zhao + + * 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 Janus Weil diff --git a/gcc/testsuite/g++.dg/conversion/ptrmem9.C b/gcc/testsuite/g++.dg/conversion/ptrmem9.C index 2ccd6837c47..d4a260f9273 100644 --- a/gcc/testsuite/g++.dg/conversion/ptrmem9.C +++ b/gcc/testsuite/g++.dg/conversion/ptrmem9.C @@ -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" } } diff --git a/gcc/testsuite/g++.dg/expr/cond2.C b/gcc/testsuite/g++.dg/expr/cond2.C index d9c2e7031f6..68a26a22f34 100644 --- a/gcc/testsuite/g++.dg/expr/cond2.C +++ b/gcc/testsuite/g++.dg/expr/cond2.C @@ -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" } } diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900324_02.C b/gcc/testsuite/g++.old-deja/g++.bugs/900324_02.C index bb612c66be4..b77cc0375a8 100644 --- a/gcc/testsuite/g++.old-deja/g++.bugs/900324_02.C +++ b/gcc/testsuite/g++.old-deja/g++.bugs/900324_02.C @@ -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; } diff --git a/gcc/testsuite/g++.old-deja/g++.jason/rfg20.C b/gcc/testsuite/g++.old-deja/g++.jason/rfg20.C index 379629456a3..505f7c94968 100644 --- a/gcc/testsuite/g++.old-deja/g++.jason/rfg20.C +++ b/gcc/testsuite/g++.old-deja/g++.jason/rfg20.C @@ -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* } diff --git a/gcc/testsuite/g++.old-deja/g++.law/typeck1.C b/gcc/testsuite/g++.old-deja/g++.law/typeck1.C index 2b5e230274a..12a8ff6e8cf 100644 --- a/gcc/testsuite/g++.old-deja/g++.law/typeck1.C +++ b/gcc/testsuite/g++.old-deja/g++.law/typeck1.C @@ -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" } } diff --git a/gcc/testsuite/g++.old-deja/g++.rfg/00321_01-.C b/gcc/testsuite/g++.old-deja/g++.rfg/00321_01-.C index 8d0f35efff6..dcc607e329a 100644 --- a/gcc/testsuite/g++.old-deja/g++.rfg/00321_01-.C +++ b/gcc/testsuite/g++.old-deja/g++.rfg/00321_01-.C @@ -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.* } diff --git a/gcc/testsuite/g++.old-deja/g++.rfg/00324_02-.C b/gcc/testsuite/g++.old-deja/g++.rfg/00324_02-.C index 4fc2a50641b..1e742cb0d04 100644 --- a/gcc/testsuite/g++.old-deja/g++.rfg/00324_02-.C +++ b/gcc/testsuite/g++.old-deja/g++.rfg/00324_02-.C @@ -12,5 +12,5 @@ int i; void test () { - i ? f : fp; // { dg-error "" } + i ? f : fp; // { dg-error "conditional expression|invalid conversion" } }