summaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 1539ad21387..aab4fac9edb 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -2647,8 +2647,16 @@ fold_convert_loc (location_t loc, tree type, tree arg)
switch (TREE_CODE (type))
{
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ /* Handle conversions between pointers to different address spaces. */
+ if (POINTER_TYPE_P (orig)
+ && (TYPE_ADDR_SPACE (TREE_TYPE (type))
+ != TYPE_ADDR_SPACE (TREE_TYPE (orig))))
+ return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, arg);
+ /* fall through */
+
case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
- case POINTER_TYPE: case REFERENCE_TYPE:
case OFFSET_TYPE:
if (TREE_CODE (arg) == INTEGER_CST)
{
@@ -3179,6 +3187,12 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
|| POINTER_TYPE_P (TREE_TYPE (arg0)) != POINTER_TYPE_P (TREE_TYPE (arg1)))
return 0;
+ /* We cannot consider pointers to different address space equal. */
+ if (POINTER_TYPE_P (TREE_TYPE (arg0)) && POINTER_TYPE_P (TREE_TYPE (arg1))
+ && (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0)))
+ != TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg1)))))
+ return 0;
+
/* If both types don't have the same precision, then it is not safe
to strip NOPs. */
if (TYPE_PRECISION (TREE_TYPE (arg0)) != TYPE_PRECISION (TREE_TYPE (arg1)))
@@ -8682,6 +8696,11 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
tem = fold_convert_const (code, type, op0);
return tem ? tem : NULL_TREE;
+ case ADDR_SPACE_CONVERT_EXPR:
+ if (integer_zerop (arg0))
+ return fold_convert_const (code, type, arg0);
+ return NULL_TREE;
+
case FIXED_CONVERT_EXPR:
tem = fold_convert_const (code, type, arg0);
return tem ? tem : NULL_TREE;