I am currently bootstrapping and regtesting the following for backport
to the 4.8 branch and the testcase for 4.9 to trunk.

Richard.

2015-06-18  Richard Biener  <rguent...@suse.de>

        Backport from mainline
        2014-12-04  Marek Polacek  <pola...@redhat.com>

        PR middle-end/56917
        * fold-const.c (fold_unary_loc): Perform the negation in A's type
        when transforming ~ (A - 1) or ~ (A + -1) to -A.

        * g++.dg/other/const4.C: New testcase.

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 221345)
+++ gcc/fold-const.c    (revision 221346)
@@ -8324,9 +8324,14 @@ fold_unary_loc (location_t loc, enum tre
                    && integer_onep (TREE_OPERAND (arg0, 1)))
                   || (TREE_CODE (arg0) == PLUS_EXPR
                       && integer_all_onesp (TREE_OPERAND (arg0, 1)))))
-       return fold_build1_loc (loc, NEGATE_EXPR, type,
-                           fold_convert_loc (loc, type,
-                                             TREE_OPERAND (arg0, 0)));
+       {
+         /* Perform the negation in ARG0's type and only then convert
+            to TYPE as to avoid introducing undefined behavior.  */
+         tree t = fold_build1_loc (loc, NEGATE_EXPR,
+                                   TREE_TYPE (TREE_OPERAND (arg0, 0)),
+                                   TREE_OPERAND (arg0, 0));
+         return fold_convert_loc (loc, type, t);
+       }
       /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify.  */
       else if (TREE_CODE (arg0) == BIT_XOR_EXPR
               && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type,


Index: gcc/testsuite/g++.dg/other/const4.C
===================================================================
*** gcc/testsuite/g++.dg/other/const4.C (revision 0)
--- gcc/testsuite/g++.dg/other/const4.C (working copy)
***************
*** 0 ****
--- 1,10 ----
+ // { dg-do compile }
+ 
+ int lValue;
+ int main()
+ {
+   switch (lValue)
+     {
+     case -(int)((2U << (8 * sizeof(int) - 2)) - 1) - 1:;
+     }
+ }

Reply via email to