diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2015-05-28 15:45:08 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2015-05-28 15:45:08 +0000 |
commit | 396e67d21a3194da9d036bdb67e74edfd1030d3f (patch) | |
tree | e352ee1b9a722c241fbc82e1122572bc6e8956cd /gcc/ada | |
parent | afd6f7023570710172c76f5afc870d7ebd32678e (diff) | |
download | gcc-396e67d21a3194da9d036bdb67e74edfd1030d3f.zip gcc-396e67d21a3194da9d036bdb67e74edfd1030d3f.tar.gz gcc-396e67d21a3194da9d036bdb67e74edfd1030d3f.tar.bz2 |
utils.c (max_size): Add special code to deal with the subtraction of a "negative" value in an...
* gcc-interface/utils.c (max_size) <tcc_binary>: Add special code to
deal with the subtraction of a "negative" value in an unsigned type.
From-SVN: r223837
Diffstat (limited to 'gcc/ada')
-rw-r--r-- | gcc/ada/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 16 |
2 files changed, 20 insertions, 1 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 8ebf666..61ec1df 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,10 @@ 2015-05-28 Eric Botcazou <ebotcazou@adacore.com> + * gcc-interface/utils.c (max_size) <tcc_binary>: Add special code to + deal with the subtraction of a "negative" value in an unsigned type. + +2015-05-28 Eric Botcazou <ebotcazou@adacore.com> + * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Subprogram_Type>: Do not error out on a return type which has a size that overflows if the return is done by invisible reference. diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 7615d2d..0871c3c 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -3443,9 +3443,23 @@ max_size (tree exp, bool max_p) if ((code == MINUS_EXPR || code == PLUS_EXPR) && TREE_CODE (lhs) == INTEGER_CST && TREE_OVERFLOW (lhs) - && !TREE_CONSTANT (rhs)) + && TREE_CODE (rhs) != INTEGER_CST) return lhs; + /* If we are going to subtract a "negative" value in an unsigned type, + do the operation as an addition of the negated value, in order to + avoid creating a spurious overflow below. */ + if (code == MINUS_EXPR + && TYPE_UNSIGNED (type) + && TREE_CODE (rhs) == INTEGER_CST + && !TREE_OVERFLOW (rhs) + && tree_int_cst_sign_bit (rhs) != 0) + { + rhs = fold_build1 (NEGATE_EXPR, type, rhs); + code = PLUS_EXPR; + } + + /* We need to detect overflows so we call size_binop here. */ return size_binop (code, lhs, rhs); } |