summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-06 13:37:58 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-06 13:37:58 +0000
commit8822b88567443be7228beb3097b927744a6bad0c (patch)
tree416997b33906d5c835be090548d2bc7556824351
parent864a438fb6bab4f861727ba298bfa7ea26232921 (diff)
downloadgcc-8822b88567443be7228beb3097b927744a6bad0c.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161869 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/convert.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr44828.c19
4 files changed, 39 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7c3c3f12852..e25324e765d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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 ...
diff --git a/gcc/convert.c b/gcc/convert.c
index f54b6d9adfe..5fe4d5712f6 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d0b1b14c1a2..d4225d7fb04 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..e16be2dc757
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr44828.c
@@ -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;
+}
+