re PR c++/37004 ([C++ only] Wconversion warns for short y = 0x7fff; short z = (short) x & y;)

2008-10-20  Manuel López-Ibáñez  <manu@gcc.gnu.org>

	PR c++/37004
cp/
	* 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.
testsuite/
	* g++.dg/warn/Wconversion-pr34389.C: Remove XFAIL.

From-SVN: r141233
parent 641afcff
2008-10-20 Manuel López-Ibáñez <manu@gcc.gnu.org>
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 <jakub@redhat.com> 2008-10-14 Jakub Jelinek <jakub@redhat.com>
PR c++/37819 PR c++/37819
......
...@@ -4959,6 +4959,7 @@ extern void cp_apply_type_quals_to_decl (int, tree); ...@@ -4959,6 +4959,7 @@ extern void cp_apply_type_quals_to_decl (int, tree);
extern tree build_ptrmemfunc1 (tree, tree, tree); extern tree build_ptrmemfunc1 (tree, tree, tree);
extern void expand_ptrmemfunc_cst (tree, tree *, tree *); 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 composite_pointer_type (tree, tree, tree, tree, extern tree composite_pointer_type (tree, tree, tree, tree,
const char*, tsubst_flags_t); const char*, tsubst_flags_t);
extern tree merge_types (tree, tree); extern tree merge_types (tree, tree);
......
...@@ -248,12 +248,13 @@ original_type (tree t) ...@@ -248,12 +248,13 @@ original_type (tree t)
return cp_build_qualified_type (t, quals); return cp_build_qualified_type (t, quals);
} }
/* T1 and T2 are arithmetic or enumeration types. Return the type /* Return the common type for two arithmetic types T1 and T2 under the
that will result from the "usual arithmetic conversions" on T1 and usual arithmetic conversions. The default conversions have already
T2 as described in [expr]. */ been applied, and enumerated types converted to their compatible
integer types. */
tree static tree
type_after_usual_arithmetic_conversions (tree t1, tree t2) cp_common_type (tree t1, tree t2)
{ {
enum tree_code code1 = TREE_CODE (t1); enum tree_code code1 = TREE_CODE (t1);
enum tree_code code2 = TREE_CODE (t2); enum tree_code code2 = TREE_CODE (t2);
...@@ -307,13 +308,6 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2) ...@@ -307,13 +308,6 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2)
if (code2 == REAL_TYPE && code1 != REAL_TYPE) if (code2 == REAL_TYPE && code1 != REAL_TYPE)
return build_type_attribute_variant (t2, attributes); 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. */ /* Both real or both integers; use the one with greater precision. */
if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2)) if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
return build_type_attribute_variant (t1, attributes); return build_type_attribute_variant (t1, attributes);
...@@ -393,6 +387,31 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2) ...@@ -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 /* Subroutine of composite_pointer_type to implement the recursive
case. See that function for documentation fo the parameters. */ case. See that function for documentation fo the parameters. */
...@@ -744,39 +763,42 @@ merge_types (tree t1, tree t2) ...@@ -744,39 +763,42 @@ merge_types (tree t1, tree t2)
return cp_build_type_attribute_variant (t1, attributes); return cp_build_type_attribute_variant (t1, attributes);
} }
/* Return the common type of two types. /* Wrapper around cp_common_type that is used by c-common.c and other
We assume that comptypes has already been done and returned 1; front end optimizations that remove promotions.
if that isn't so, this may crash.
This is the type for the result of most arithmetic operations Return the common type for two arithmetic types T1 and T2 under the
if the operands have the given two types. */ usual arithmetic conversions. The default conversions have already
been applied, and enumerated types converted to their compatible
integer types. */
tree tree
common_type (tree t1, tree t2) common_type (tree t1, tree t2)
{ {
enum tree_code code1; /* If one type is nonsense, use the other */
enum tree_code code2; if (t1 == error_mark_node)
return t2;
if (t2 == error_mark_node)
return t1;
/* If one type is nonsense, bail. */ return cp_common_type (t1, t2);
if (t1 == error_mark_node || t2 == error_mark_node) }
return error_mark_node;
code1 = TREE_CODE (t1); /* Return the common type of two pointer types T1 and T2. This is the
code2 = TREE_CODE (t2); 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) tree
|| code1 == VECTOR_TYPE) common_pointer_type (tree t1, tree t2)
&& (ARITHMETIC_TYPE_P (t2) || UNSCOPED_ENUM_P (t2) {
|| code2 == VECTOR_TYPE)) gcc_assert ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
return type_after_usual_arithmetic_conversions (t1, 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)) return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
|| (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2))) "conversion", tf_warning_or_error);
return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
"conversion", tf_warning_or_error);
else
gcc_unreachable ();
} }
/* Compare two exception specifier types for exactness or subsetness, if /* Compare two exception specifier types for exactness or subsetness, if
...@@ -3303,7 +3325,7 @@ cp_build_binary_op (location_t location, ...@@ -3303,7 +3325,7 @@ cp_build_binary_op (location_t location,
if (code0 == POINTER_TYPE && code1 == POINTER_TYPE if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
&& same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0), && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
TREE_TYPE (type1))) 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 /* In all other cases except pointer - int, the usual arithmetic
rules apply. */ rules apply. */
else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE)) else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
...@@ -3805,7 +3827,7 @@ cp_build_binary_op (location_t location, ...@@ -3805,7 +3827,7 @@ cp_build_binary_op (location_t location,
if (!result_type if (!result_type
&& arithmetic_types_p && arithmetic_types_p
&& (shorten || common || short_compare)) && (shorten || common || short_compare))
result_type = common_type (type0, type1); result_type = cp_common_type (type0, type1);
if (!result_type) if (!result_type)
{ {
......
2008-10-20 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c++/37004
* g++.dg/warn/Wconversion-pr34389.C: Remove XFAIL.
2008-10-19 Manuel López-Ibáñez <manu@gcc.gnu.org> 2008-10-19 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c/30260 PR c/30260
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
short mask1(short x) short mask1(short x)
{ {
short y = 0x7fff; short y = 0x7fff;
return x & y; /* { dg-bogus "conversion" "conversion" { xfail *-*-* } 8 } */ return x & y; /* { dg-bogus "conversion" "bogus warning" } */
} }
short mask2(short ssx) short mask2(short ssx)
......
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