From: ebotcazou Date: Thu, 28 May 2015 15:45:08 +0000 (+0000) Subject: * gcc-interface/utils.c (max_size) : Add special code to X-Git-Tag: upstream/6.1~6812 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4c3f1f54082dddcf3a7b29d52b160480ec7f838b;p=platform%2Fupstream%2Flinaro-gcc.git * gcc-interface/utils.c (max_size) : Add special code to deal with the subtraction of a "negative" value in an unsigned type. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@223837 138bc75d-0d04-0410-961f-82ee72b054a4 --- 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 + * gcc-interface/utils.c (max_size) : Add special code to + deal with the subtraction of a "negative" value in an unsigned type. + +2015-05-28 Eric Botcazou + * gcc-interface/decl.c (gnat_to_gnu_entity) : 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 + * gnat.dg/discr43.adb: New test. + +2015-05-28 Eric Botcazou + * 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;