]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c/44828 (possible integer wrong code bug)
authorRichard Guenther <rguenther@suse.de>
Tue, 6 Jul 2010 13:37:58 +0000 (13:37 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 6 Jul 2010 13:37:58 +0000 (13:37 +0000)
2010-07-06  Richard Guenther  <rguenther@suse.de>

PR middle-end/44828
* convert.c (convert_to_integer): Watch out for overflowing
MULT_EXPR as well.

* gcc.c-torture/execute/pr44828.c: New testcase.

From-SVN: r161869

gcc/ChangeLog
gcc/convert.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr44828.c [new file with mode: 0644]

index 7c3c3f128523afa8fb6817b9121449cbc8a4d0bd..e25324e765de9563285a082c64b666da9af0aa2b 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-06  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/44828
+       * convert.c (convert_to_integer): Watch out for overflowing
+       MULT_EXPR as well.
+
 2010-07-05  Jan Hubicka  <jh@suse.cz>
 
        * lto-streamer.c (write_symbol_vec): Rename to ...
index f54b6d9adfe51b221ab5ecbf1035f8fdd4e04416..5fe4d5712f61c9d5060774b9a0c46a0de33b46f4 100644 (file)
@@ -768,13 +768,19 @@ convert_to_integer (tree type, tree expr)
                        || ex_form == LSHIFT_EXPR
                        /* If we have !flag_wrapv, and either ARG0 or
                           ARG1 is of a signed type, we have to do
-                          PLUS_EXPR or MINUS_EXPR in an unsigned
-                          type.  Otherwise, we would introduce
+                          PLUS_EXPR, MINUS_EXPR or MULT_EXPR in an unsigned
+                          type in case the operation in outprec precision
+                          could overflow.  Otherwise, we would introduce
                           signed-overflow undefinedness.  */
                        || ((!TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0))
                             || !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1)))
+                           && ((TYPE_PRECISION (TREE_TYPE (arg0)) * 2u
+                                > outprec)
+                               || (TYPE_PRECISION (TREE_TYPE (arg1)) * 2u
+                                   > outprec))
                            && (ex_form == PLUS_EXPR
-                               || ex_form == MINUS_EXPR)))
+                               || ex_form == MINUS_EXPR
+                               || ex_form == MULT_EXPR)))
                      typex = unsigned_type_for (typex);
                    else
                      typex = signed_type_for (typex);
index d0b1b14c1a2d0f42676e28321de53cfaa2435aa6..d4225d7fb0496553eb6a4f5d5a9dc422bdb19fb4 100644 (file)
@@ -1,3 +1,8 @@
+2010-07-06  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/44828
+       * gcc.c-torture/execute/pr44828.c: New testcase.
+
 2010-07-06  Shujing Zhao  <pearly.zhao@oracle.com>
 
        * g++.dg/warn/noeffect2.C: Adjust expected warning.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr44828.c b/gcc/testsuite/gcc.c-torture/execute/pr44828.c
new file mode 100644 (file)
index 0000000..e16be2d
--- /dev/null
@@ -0,0 +1,19 @@
+extern void abort (void);
+
+static char
+foo (char si1, char si2)
+{
+  return si1 * si2;
+}
+
+int a = 0x105F61CA;
+
+int
+main (void)
+{
+  int b = 0x0332F5C8;
+  if (foo (b, a) > 0)
+    abort ();
+  return 0;
+}
+