OSDN Git Service

PR tree-optimization/45047
[pf3gnuchains/gcc-fork.git] / gcc / convert.c
index f54b6d9..48f3f94 100644 (file)
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "flags.h"
 #include "convert.h"
+#include "diagnostic-core.h"
 #include "toplev.h"
 #include "langhooks.h"
 
@@ -768,13 +769,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);