aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2015-05-28 15:45:08 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2015-05-28 15:45:08 +0000
commit396e67d21a3194da9d036bdb67e74edfd1030d3f (patch)
treee352ee1b9a722c241fbc82e1122572bc6e8956cd /gcc
parentafd6f7023570710172c76f5afc870d7ebd32678e (diff)
downloadgcc-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')
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/gcc-interface/utils.c16
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/discr43.adb16
4 files changed, 40 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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 282a3be..f986488 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2015-05-28 Eric Botcazou <ebotcazou@adacore.com>
+ * gnat.dg/discr43.adb: New test.
+
+2015-05-28 Eric Botcazou <ebotcazou@adacore.com>
+
* gnat.dg/varsize_temp.adb: Rename into...
* gnat.dg/varsize1.adb: ...this.
* gnat.dg/varsize_copy.ad[sb]: Rename into...
diff --git a/gcc/testsuite/gnat.dg/discr43.adb b/gcc/testsuite/gnat.dg/discr43.adb
new file mode 100644
index 0000000..e0d4390
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr43.adb
@@ -0,0 +1,16 @@
+-- { dg-do compile }
+
+with Text_IO; use Text_IO;
+
+procedure Discr43 is
+
+ type Arr is array (Short_Integer range <>) of Boolean;
+
+ type Rec (LB : Short_Integer; UB : Short_Integer) is record
+ A : Arr (LB .. UB);
+ end record;
+
+begin
+ Put_Line ("Arr'Max_Size =" & Arr'Max_Size_In_Storage_Elements'Img);
+ Put_Line ("Rec'Max_Size =" & Rec'Max_Size_In_Storage_Elements'Img);
+end;