re PR c++/36741 (Bogus "large integer implicitly truncated" passing size_t constant...
authorDodji Seketeli <dodji@redhat.com>
Thu, 28 Aug 2008 14:49:48 +0000 (14:49 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Thu, 28 Aug 2008 14:49:48 +0000 (16:49 +0200)
2008-08-28  Dodji Seketeli  <dodji@redhat.com>

PR c++/36741
* tree.c (int_fits_type_p): Don't forget unsigned integers
  of type sizetype which higher end word equals -1.

From-SVN: r139712

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/new-size-type.C [new file with mode: 0644]
gcc/tree.c

index 1f7396f..4af737e 100644 (file)
@@ -1,3 +1,9 @@
+2008-08-28  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/36741
+       * tree.c (int_fits_type_p): Don't forget unsigned integers
+         of type sizetype which higher end word equals -1.
+
 2008-08-28  Ira Rosen  <irar@il.ibm.com>
 
        * target.h (struct vectorize): Add new target builtin.
index d5b6c83..3eed73a 100644 (file)
@@ -1,3 +1,8 @@
+2008-08-28  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/36741
+       * g++.dg/other/new-size-type.C: New test.
+
 2008-08-28  Ira Rosen  <irar@il.ibm.com>
 
        * lib/target-supports.exp (check_effective_target_vect_perm): New.
diff --git a/gcc/testsuite/g++.dg/other/new-size-type.C b/gcc/testsuite/g++.dg/other/new-size-type.C
new file mode 100644 (file)
index 0000000..04933fd
--- /dev/null
@@ -0,0 +1,10 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin: PR c++/36741
+
+#include <stddef.h>
+const char*
+foo()
+{
+    return new char[~static_cast<size_t>(0)];// { dg-bogus "large" }
+}
+
index 912d77f..f058fd7 100644 (file)
@@ -6319,6 +6319,21 @@ int_fits_type_p (const_tree c, const_tree type)
      for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
      for "constant known to fit".  */
 
+  if (TREE_TYPE (c) == sizetype
+      && TYPE_UNSIGNED (TREE_TYPE (c))
+      && TREE_INT_CST_HIGH (c) == -1
+      && !TREE_OVERFLOW (c))
+      /* So c is an unsigned integer which type is sizetype.
+         sizetype'd integers are sign extended even though they are
+        unsigned. If the integer value fits in the lower end word of c,
+        and if the higher end word has all its bits set to 1, that
+        means the higher end bits are set to 1 only for sign extension.
+        So let's convert c into an equivalent zero extended unsigned
+        integer.  */
+      c = force_fit_type_double (size_type_node,
+                                TREE_INT_CST_LOW (c),
+                                TREE_INT_CST_HIGH (c),
+                                false, false);
   /* Check if C >= type_low_bound.  */
   if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
     {