re PR tree-optimization/81603 (Various compiler UB on very large constant offsets)
authorJakub Jelinek <jakub@redhat.com>
Mon, 31 Jul 2017 08:22:14 +0000 (10:22 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 31 Jul 2017 08:22:14 +0000 (10:22 +0200)
PR tree-optimization/81603
* ipa-polymorphic-call.c
(ipa_polymorphic_call_context::ipa_polymorphic_call_context): Perform
offset arithmetic in offset_int, bail out if the resulting bit offset
doesn't fit into shwi.

From-SVN: r250727

gcc/ChangeLog
gcc/ipa-polymorphic-call.c

index 59ddc50a8066911b301ae67b508b02a56fc8813e..318a98593518a1601d30d4b965a75348b02903bc 100644 (file)
@@ -1,3 +1,11 @@
+2017-07-31  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/81603
+       * ipa-polymorphic-call.c
+       (ipa_polymorphic_call_context::ipa_polymorphic_call_context): Perform
+       offset arithmetic in offset_int, bail out if the resulting bit offset
+       doesn't fit into shwi.
+
 2017-07-31  Martin Liska  <mliska@suse.cz>
 
        * gimplify.c (mostly_copy_tree_r): Remove Java specific hunk.
index 6b9f82138dc3db4b21c015d680964d39be127416..9ac5153bf6716d5ed4a40ca885d74ae315153493 100644 (file)
@@ -921,9 +921,13 @@ ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl,
                 and MEM_REF is meaningless, but we can look futher.  */
              if (TREE_CODE (base) == MEM_REF)
                {
+                 offset_int o = mem_ref_offset (base) * BITS_PER_UNIT;
+                 o += offset;
+                 o += offset2;
+                 if (!wi::fits_shwi_p (o))
+                   break;
                  base_pointer = TREE_OPERAND (base, 0);
-                 offset
-                   += offset2 + mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
+                 offset = o.to_shwi ();
                  outer_type = NULL;
                }
              /* We found base object.  In this case the outer_type
@@ -961,10 +965,15 @@ ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl,
            break;
        }
       else if (TREE_CODE (base_pointer) == POINTER_PLUS_EXPR
-              && tree_fits_uhwi_p (TREE_OPERAND (base_pointer, 1)))
+              && TREE_CODE (TREE_OPERAND (base_pointer, 1)) == INTEGER_CST)
        {
-         offset += tree_to_shwi (TREE_OPERAND (base_pointer, 1))
-                   * BITS_PER_UNIT;
+         offset_int o = offset_int::from (TREE_OPERAND (base_pointer, 1),
+                                          SIGNED);
+         o *= BITS_PER_UNIT;
+         o += offset;
+         if (!wi::fits_shwi_p (o))
+           break;
+         offset = o.to_shwi ();
          base_pointer = TREE_OPERAND (base_pointer, 0);
        }
       else