aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2008-08-28 14:49:48 +0000
committerDodji Seketeli <dodji@gcc.gnu.org>2008-08-28 16:49:48 +0200
commit5bdc1946f07880739cdbca20105cebcba5795de0 (patch)
treecedeeece4140a9cc8474c6215439d0802ddad3f1
parent0fca40f598654f83453b17e44f902183859b16e4 (diff)
downloadgcc-5bdc1946f07880739cdbca20105cebcba5795de0.zip
gcc-5bdc1946f07880739cdbca20105cebcba5795de0.tar.gz
gcc-5bdc1946f07880739cdbca20105cebcba5795de0.tar.bz2
re PR c++/36741 (Bogus "large integer implicitly truncated" passing size_t constant to new)
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/other/new-size-type.C10
-rw-r--r--gcc/tree.c15
4 files changed, 36 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1f7396f..4af737e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d5b6c83..3eed73a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..04933fd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/new-size-type.C
@@ -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" }
+}
+
diff --git a/gcc/tree.c b/gcc/tree.c
index 912d77f..f058fd7 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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)
{