aboutsummaryrefslogtreecommitdiff
path: root/gcc/convert.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-07-06 13:37:58 +0000
committerRichard Guenther <rguenther@suse.de>2010-07-06 13:37:58 +0000
commit40ff0b64f89905292dfcecf24fa7c292da62372f (patch)
tree416997b33906d5c835be090548d2bc7556824351 /gcc/convert.c
parent3c466bf7b980da036c80eb0f859e6a386b3cde88 (diff)
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: https://gcc.gnu.org/svn/gcc/trunk@161869 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/convert.c')
-rw-r--r--gcc/convert.c12
1 files changed, 9 insertions, 3 deletions
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);