aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorManuel López-Ibáñez <manu@gcc.gnu.org>2008-10-19 22:53:01 +0000
committerManuel López-Ibáñez <manu@gcc.gnu.org>2008-10-19 22:53:01 +0000
commit98f2f3a24f2706623b054a6f9b38cfd706f20ed4 (patch)
treeefc7e715925fd1cb536642887f046421f2e8cfc7 /gcc/cp
parent641afcff1d00be2cabd95d589a66a5d87ed1edda (diff)
downloadgcc-98f2f3a24f2706623b054a6f9b38cfd706f20ed4.zip
gcc-98f2f3a24f2706623b054a6f9b38cfd706f20ed4.tar.gz
gcc-98f2f3a24f2706623b054a6f9b38cfd706f20ed4.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog16
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/typeck.c100
3 files changed, 78 insertions, 39 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 30110cc..3d30c15 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3d52d83..7ff5824 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 b115e28..9e65bdd 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);
-
- 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 ();
+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)));
+
+ 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)
{