if (type_precision (intype) == POINTER_SIZE)
return build1 (CONVERT_EXPR, type, expr);
expr = convert (type_for_size (POINTER_SIZE, 0), expr);
- if (TYPE_MODE (TREE_TYPE (expr)) != TYPE_MODE (type))
+ /* Modes may be different but sizes should be the same. */
+ if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr)))
+ != GET_MODE_SIZE (TYPE_MODE (type)))
/* There is supposed to be some integral type
that is the same width as a pointer. */
abort ();
if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
return build1 (FLOAT_EXPR, type, expr);
+ if (form == COMPLEX_TYPE)
+ return convert (type, fold (build1 (REALPART_EXPR,
+ TREE_TYPE (TREE_TYPE (expr)), expr)));
+
if (form == POINTER_TYPE)
error ("pointer value used where a floating point value was expected");
else
{
register tree tem = make_node (REAL_CST);
TREE_TYPE (tem) = type;
- TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0");
+ TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0", TYPE_MODE (type));
return tem;
}
}
/* In this case, shifting is like multiplication. */
goto trunc1;
else
- /* If it is >= that width, result is zero.
- Handling this with trunc1 would give the wrong result:
- (int) ((long long) a << 32) is well defined (as 0)
- but (int) a << 32 is undefined and would get a warning. */
- return convert_to_integer (type, integer_zero_node);
+ {
+ /* If it is >= that width, result is zero.
+ Handling this with trunc1 would give the wrong result:
+ (int) ((long long) a << 32) is well defined (as 0)
+ but (int) a << 32 is undefined and would get a
+ warning. */
+
+ tree t = convert_to_integer (type, integer_zero_node);
+
+ /* If the original expression had side-effects, we must
+ preserve it. */
+ if (TREE_SIDE_EFFECTS (expr))
+ return build (COMPOUND_EXPR, type, expr, t);
+ else
+ return t;
+ }
}
break;
|| TREE_UNSIGNED (TREE_TYPE (arg1)))
? unsigned_type (typex) : signed_type (typex));
return convert (type,
- build_binary_op (ex_form,
- convert (typex, arg0),
- convert (typex, arg1),
- 0));
+ fold (build (ex_form, typex,
+ convert (typex, arg0),
+ convert (typex, arg1),
+ 0)));
}
}
}
typex = (TREE_UNSIGNED (TREE_TYPE (expr))
? unsigned_type (typex) : signed_type (typex));
return convert (type,
- build_unary_op (ex_form,
- convert (typex, TREE_OPERAND (expr, 0)),
- 1));
+ fold (build1 (ex_form, typex,
+ convert (typex,
+ TREE_OPERAND (expr, 0)))));
}
}
if (form == REAL_TYPE)
return build1 (FIX_TRUNC_EXPR, type, expr);
+ if (form == COMPLEX_TYPE)
+ return convert (type, fold (build1 (REALPART_EXPR,
+ TREE_TYPE (TREE_TYPE (expr)), expr)));
+
error ("aggregate value used where an integer was expected");
{
return tem;
}
}
+
+/* Convert EXPR to the complex type TYPE in the usual ways. */
+
+tree
+convert_to_complex (type, expr)
+ tree type, expr;
+{
+ register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
+ tree subtype = TREE_TYPE (type);
+
+ if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
+ {
+ expr = convert (subtype, expr);
+ return build (COMPLEX_EXPR, type, expr,
+ convert (subtype, integer_zero_node));
+ }
+
+ if (form == COMPLEX_TYPE)
+ {
+ tree elt_type = TREE_TYPE (TREE_TYPE (expr));
+ if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
+ return expr;
+ else if (TREE_CODE (expr) == COMPLEX_EXPR)
+ return fold (build (COMPLEX_EXPR,
+ type,
+ convert (subtype, TREE_OPERAND (expr, 0)),
+ convert (subtype, TREE_OPERAND (expr, 1))));
+ else
+ {
+ expr = save_expr (expr);
+ return fold (build (COMPLEX_EXPR,
+ type,
+ convert (subtype,
+ fold (build1 (REALPART_EXPR,
+ TREE_TYPE (TREE_TYPE (expr)),
+ expr))),
+ convert (subtype,
+ fold (build1 (IMAGPART_EXPR,
+ TREE_TYPE (TREE_TYPE (expr)),
+ expr)))));
+ }
+ }
+
+ if (form == POINTER_TYPE)
+ error ("pointer value used where a complex was expected");
+ else
+ error ("aggregate value used where a complex was expected");
+
+ return build (COMPLEX_EXPR, type,
+ convert (subtype, integer_zero_node),
+ convert (subtype, integer_zero_node));
+}