aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 030bcb1..ce68929 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -7323,7 +7323,8 @@ fold_unary (enum tree_code code, tree type, tree op0)
type via an object of identical or wider precision, neither
conversion is needed. */
if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (type)
- && ((inter_int && final_int) || (inter_float && final_float))
+ && (((inter_int || inter_ptr) && final_int)
+ || (inter_float && final_float))
&& inter_prec >= final_prec)
return fold_build1 (code, type, TREE_OPERAND (op0, 0));
@@ -7362,10 +7363,13 @@ fold_unary (enum tree_code code, tree type, tree op0)
- the initial type is a pointer type and the precisions of the
intermediate and final types differ, or
- the final type is a pointer type and the precisions of the
- initial and intermediate types differ. */
+ initial and intermediate types differ.
+ - the final type is a pointer type and the initial type not
+ - the initial type is a pointer to an array and the final type
+ not. */
if (! inside_float && ! inter_float && ! final_float
&& ! inside_vec && ! inter_vec && ! final_vec
- && (inter_prec > inside_prec || inter_prec > final_prec)
+ && (inter_prec >= inside_prec || inter_prec >= final_prec)
&& ! (inside_int && inter_int
&& inter_unsignedp != inside_unsignedp
&& inter_prec < final_prec)
@@ -7375,7 +7379,10 @@ fold_unary (enum tree_code code, tree type, tree op0)
&& ! (final_ptr && inside_prec != inter_prec)
&& ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
&& TYPE_MODE (type) == TYPE_MODE (inter_type))
- && ! final_ptr)
+ && final_ptr == inside_ptr
+ && ! (inside_ptr
+ && TREE_CODE (TREE_TYPE (inside_type)) == ARRAY_TYPE
+ && TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
return fold_build1 (code, type, TREE_OPERAND (op0, 0));
}