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
This commit is contained in:
Manuel López-Ibáñez 2008-10-19 22:53:01 +00:00
parent 641afcff1d
commit 98f2f3a24f
5 changed files with 83 additions and 39 deletions

View File

@ -1,3 +1,19 @@
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>
PR c++/37819

View File

@ -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);

View File

@ -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)
{

View File

@ -1,3 +1,8 @@
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>
PR c/30260

View File

@ -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)