diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 30110cca72c..3d30c15819d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2008-10-20 Manuel López-Ibáñez + + PR c++/37004 + * typeck.c (cp_common_type): New. The same as + type_after_usual_arithmetic_conversions but without promotions. + (type_after_usual_arithmetic_conversions): Do the promotions and + call cp_common_type. + (common_type): Make it behave like the C version of this + function. Do not handle pointer types. + (common_pointer_type): Move handling of pointer types from + common_type to here. + (cp_build_binary_op): Use common_pointer_type instead of + common_type in call to pointer_diff. + Use cp_common_type instead of common_type. + * cp-tree.h (common_pointer_type): Declare. + 2008-10-14 Jakub Jelinek PR c++/37819 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3d52d83b448..7ff5824180a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4959,6 +4959,7 @@ extern void cp_apply_type_quals_to_decl (int, tree); extern tree build_ptrmemfunc1 (tree, tree, tree); 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); extern tree merge_types (tree, tree); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index b115e2871d8..9e65bdd3a11 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -248,12 +248,13 @@ original_type (tree t) return cp_build_qualified_type (t, quals); } -/* T1 and T2 are arithmetic or enumeration types. Return the type - that will result from the "usual arithmetic conversions" on T1 and - T2 as described in [expr]. */ +/* Return the common type for two arithmetic types T1 and T2 under the + usual arithmetic conversions. The default conversions have already + been applied, and enumerated types converted to their compatible + integer types. */ -tree -type_after_usual_arithmetic_conversions (tree t1, tree t2) +static tree +cp_common_type (tree t1, tree t2) { enum tree_code code1 = TREE_CODE (t1); enum tree_code code2 = TREE_CODE (t2); @@ -307,13 +308,6 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2) if (code2 == REAL_TYPE && code1 != REAL_TYPE) return build_type_attribute_variant (t2, attributes); - /* Perform the integral promotions. */ - if (code1 != REAL_TYPE) - { - t1 = type_promotes_to (t1); - t2 = type_promotes_to (t2); - } - /* Both real or both integers; use the one with greater precision. */ if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2)) return build_type_attribute_variant (t1, attributes); @@ -393,6 +387,31 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2) } } +/* T1 and T2 are arithmetic or enumeration types. Return the type + that will result from the "usual arithmetic conversions" on T1 and + T2 as described in [expr]. */ + +tree +type_after_usual_arithmetic_conversions (tree t1, tree t2) +{ + gcc_assert (ARITHMETIC_TYPE_P (t1) + || TREE_CODE (t1) == VECTOR_TYPE + || UNSCOPED_ENUM_P (t1)); + gcc_assert (ARITHMETIC_TYPE_P (t2) + || TREE_CODE (t2) == VECTOR_TYPE + || UNSCOPED_ENUM_P (t2)); + + /* Perform the integral promotions. We do not promote real types here. */ + if (INTEGRAL_OR_ENUMERATION_TYPE_P (t1) + && INTEGRAL_OR_ENUMERATION_TYPE_P (t1)) + { + t1 = type_promotes_to (t1); + t2 = type_promotes_to (t2); + } + + return cp_common_type (t1, t2); +} + /* Subroutine of composite_pointer_type to implement the recursive case. See that function for documentation fo the parameters. */ @@ -744,39 +763,42 @@ merge_types (tree t1, tree t2) return cp_build_type_attribute_variant (t1, attributes); } -/* Return the common type of two types. - We assume that comptypes has already been done and returned 1; - if that isn't so, this may crash. +/* Wrapper around cp_common_type that is used by c-common.c and other + front end optimizations that remove promotions. - This is the type for the result of most arithmetic operations - if the operands have the given two types. */ + Return the common type for two arithmetic types T1 and T2 under the + usual arithmetic conversions. The default conversions have already + been applied, and enumerated types converted to their compatible + integer types. */ tree common_type (tree t1, tree t2) { - enum tree_code code1; - enum tree_code code2; + /* If one type is nonsense, use the other */ + if (t1 == error_mark_node) + return t2; + if (t2 == error_mark_node) + return t1; - /* If one type is nonsense, bail. */ - if (t1 == error_mark_node || t2 == error_mark_node) - return error_mark_node; + return cp_common_type (t1, t2); +} - code1 = TREE_CODE (t1); - code2 = TREE_CODE (t2); +/* Return the common type of two pointer types T1 and T2. This is the + type for the result of most arithmetic operations if the operands + have the given two types. + + We assume that comp_target_types has already been done and returned + nonzero; if that isn't so, this may crash. */ - if ((ARITHMETIC_TYPE_P (t1) || UNSCOPED_ENUM_P (t1) - || code1 == VECTOR_TYPE) - && (ARITHMETIC_TYPE_P (t2) || UNSCOPED_ENUM_P (t2) - || code2 == VECTOR_TYPE)) - return type_after_usual_arithmetic_conversions (t1, t2); +tree +common_pointer_type (tree t1, tree t2) +{ + gcc_assert ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2)) + || (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2)) + || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2))); - else if ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2)) - || (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (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); - else - gcc_unreachable (); + return composite_pointer_type (t1, t2, error_mark_node, error_mark_node, + "conversion", tf_warning_or_error); } /* Compare two exception specifier types for exactness or subsetness, if @@ -3303,7 +3325,7 @@ cp_build_binary_op (location_t location, if (code0 == POINTER_TYPE && code1 == POINTER_TYPE && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0), TREE_TYPE (type1))) - return pointer_diff (op0, op1, common_type (type0, type1)); + return pointer_diff (op0, op1, common_pointer_type (type0, type1)); /* In all other cases except pointer - int, the usual arithmetic rules apply. */ else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE)) @@ -3805,7 +3827,7 @@ cp_build_binary_op (location_t location, if (!result_type && arithmetic_types_p && (shorten || common || short_compare)) - result_type = common_type (type0, type1); + result_type = cp_common_type (type0, type1); if (!result_type) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a08312d98f2..0ccdae9c885 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-10-20 Manuel López-Ibáñez + + PR c++/37004 + * g++.dg/warn/Wconversion-pr34389.C: Remove XFAIL. + 2008-10-19 Manuel López-Ibáñez PR c/30260 diff --git a/gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C b/gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C index a6df4035a62..43df8f902d7 100644 --- a/gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C +++ b/gcc/testsuite/g++.dg/warn/Wconversion-pr34389.C @@ -5,7 +5,7 @@ short mask1(short x) { short y = 0x7fff; - return x & y; /* { dg-bogus "conversion" "conversion" { xfail *-*-* } 8 } */ + return x & y; /* { dg-bogus "conversion" "bogus warning" } */ } short mask2(short ssx)