This commit is contained in:
Jakub Jelinek 2012-11-09 12:58:44 +01:00
parent 8479884c4b
commit 171e01f806
6 changed files with 265 additions and 182 deletions

1
.gitignore vendored
View File

@ -46,3 +46,4 @@
/gcc-4.7.2-20121009.tar.bz2
/gcc-4.7.2-20121015.tar.bz2
/gcc-4.7.2-20121105.tar.bz2
/gcc-4.7.2-20121109.tar.bz2

View File

@ -1,9 +1,9 @@
%global DATE 20121105
%global SVNREV 193180
%global DATE 20121109
%global SVNREV 193356
%global gcc_version 4.7.2
# Note, gcc_release must be integer, if you want to add suffixes to
# %{release}, append them after %{gcc_release} on Release: line.
%global gcc_release 7
%global gcc_release 8
%global _unpackaged_files_terminate_build 0
%global multilib_64_archs sparc64 ppc64 s390x x86_64
%ifarch %{ix86} x86_64 ia64 ppc ppc64 alpha
@ -84,6 +84,9 @@ BuildRequires: binutils >= 2.20.51.0.2-12
BuildRequires: glibc-static
BuildRequires: zlib-devel, gettext, dejagnu, bison, flex, texinfo, sharutils
BuildRequires: systemtap-sdt-devel >= 1.3
%if %{build_go}
BuildRequires: hostname
%endif
# For VTA guality testing
BuildRequires: gdb
%if %{build_java}
@ -185,7 +188,8 @@ Patch14: gcc47-ppl-0.10.patch
Patch15: gcc47-libitm-fno-exceptions.patch
Patch16: gcc47-rh837630.patch
Patch17: gcc47-arm-hfp-ldso.patch
Patch18: gcc47-c++-new-check-opt.patch
Patch18: gcc47-pr55137.patch
Patch19: gcc47-pr55236.patch
Patch1000: fastjar-0.97-segfault.patch
Patch1001: fastjar-0.97-len1.patch
@ -690,7 +694,8 @@ package or when debugging this package.
%if 0%{?fedora} >= 18 || 0%{?rhel} >= 7
%patch17 -p0 -b .arm-hfp-ldso~
%endif
%patch18 -p0 -b .c++-new-check-opt~
%patch18 -p0 -b .pr55137~
%patch19 -p0 -b .pr55236~
%if 0%{?_enable_debug_packages}
cat > split-debuginfo.sh <<\EOF
@ -2664,6 +2669,17 @@ fi
%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/plugin
%changelog
* Fri Nov 9 2012 Jakub Jelinek <jakub@redhat.com> 4.7.2-8
- update from the 4.7 branch
- PRs fortran/54917, libstdc++/28811, libstdc++/54482, libstdc++/55028,
libstdc++/55215, middle-end/55219, target/55204,
tree-optimization/54986
- further debug info quality improvements
- fix reassociation (PR c++/55137)
- fix range test optimization with -fwrapv (PR tree-optimization/55236)
- add BuildRequires hostname (#875001)
- __cxa_vec_new[23] overflow checking (#875009)
* Mon Nov 5 2012 Jakub Jelinek <jakub@redhat.com> 4.7.2-7
- update from the 4.7 branch
- PRs c++/54984, c++/54988, debug/54828, libstdc++/55047, libstdc++/55123,

View File

@ -1,176 +0,0 @@
2012-10-31 Florian Weimer <fweimer@redhat.com>
* init.c (build_new_1): Do not check for arithmetic overflow if
inner array size is 1.
* g++.dg/init/new40.C: New.
--- gcc/cp/init.c (revision 193033)
+++ gcc/cp/init.c (working copy)
@@ -2176,6 +2176,8 @@ build_new_1 (VEC(tree,gc) **placement, t
double_int inner_nelts_count = double_int_one;
tree inner_nelts = NULL_TREE;
tree alloc_call, alloc_expr;
+ /* Size of the inner array elements. */
+ double_int inner_size;
/* The address returned by the call to "operator new". This node is
a VAR_DECL and is therefore reusable. */
tree alloc_node;
@@ -2318,8 +2320,6 @@ build_new_1 (VEC(tree,gc) **placement, t
double_int max_size
= double_int_lshift (double_int_one, TYPE_PRECISION (sizetype) - 1,
HOST_BITS_PER_DOUBLE_INT, false);
- /* Size of the inner array elements. */
- double_int inner_size;
/* Maximum number of outer elements which can be allocated. */
double_int max_outer_nelts;
tree max_outer_nelts_tree;
@@ -2438,7 +2438,15 @@ build_new_1 (VEC(tree,gc) **placement, t
if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))
size = size_binop (PLUS_EXPR, size, cookie_size);
else
- cookie_size = NULL_TREE;
+ {
+ cookie_size = NULL_TREE;
+ /* No size arithmetic necessary, so the size check is
+ not needed. */
+ if (outer_nelts_check != NULL
+ && double_int_one_p (inner_size)
+ && inner_nelts == NULL_TREE)
+ outer_nelts_check = NULL_TREE;
+ }
/* Perform the overflow check. */
if (outer_nelts_check != NULL_TREE)
size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check,
@@ -2474,7 +2482,15 @@ build_new_1 (VEC(tree,gc) **placement, t
/* Use a global operator new. */
/* See if a cookie might be required. */
if (!(array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type)))
- cookie_size = NULL_TREE;
+ {
+ cookie_size = NULL_TREE;
+ /* No size arithmetic necessary, so the size check is
+ not needed. */
+ if (outer_nelts_check != NULL
+ && double_int_one_p (inner_size)
+ && inner_nelts == NULL_TREE)
+ outer_nelts_check = NULL_TREE;
+ }
alloc_call = build_operator_new_call (fnname, placement,
&size, &cookie_size,
--- gcc/testsuite/g++.dg/init/new40.C (revision 0)
+++ gcc/testsuite/g++.dg/init/new40.C (working copy)
@@ -0,0 +1,112 @@
+// Testcase for overflow handling in operator new[].
+// Optimization of unnecessary overflow checks.
+// { dg-do run }
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdexcept>
+
+static size_t magic_allocation_size
+ = 1 + (size_t (1) << (sizeof (size_t) * 8 - 1));
+
+struct exc : std::bad_alloc {
+};
+
+static size_t expected_size;
+
+struct pod_with_new {
+ char ch;
+ void *operator new[] (size_t sz)
+ {
+ if (sz != expected_size)
+ abort ();
+ throw exc ();
+ }
+};
+
+struct with_new {
+ char ch;
+ with_new () { }
+ ~with_new () { }
+ void *operator new[] (size_t sz)
+ {
+ if (sz != size_t (-1))
+ abort ();
+ throw exc ();
+ }
+};
+
+struct non_pod {
+ char ch;
+ non_pod () { }
+ ~non_pod () { }
+};
+
+void *
+operator new (size_t sz) _GLIBCXX_THROW (std::bad_alloc)
+{
+ if (sz != expected_size)
+ abort ();
+ throw exc ();
+}
+
+int
+main ()
+{
+ if (sizeof (pod_with_new) == 1)
+ expected_size = magic_allocation_size;
+ else
+ expected_size = -1;
+
+ try {
+ new pod_with_new[magic_allocation_size];
+ abort ();
+ } catch (exc &) {
+ }
+
+ if (sizeof (with_new) == 1)
+ expected_size = magic_allocation_size;
+ else
+ expected_size = -1;
+
+ try {
+ new with_new[magic_allocation_size];
+ abort ();
+ } catch (exc &) {
+ }
+
+ expected_size = magic_allocation_size;
+ try {
+ new char[magic_allocation_size];
+ abort ();
+ } catch (exc &) {
+ }
+
+ expected_size = -1;
+
+ try {
+ new pod_with_new[magic_allocation_size][2];
+ abort ();
+ } catch (exc &) {
+ }
+
+ try {
+ new with_new[magic_allocation_size][2];
+ abort ();
+ } catch (exc &) {
+ }
+
+ try {
+ new char[magic_allocation_size][2];
+ abort ();
+ } catch (exc &) {
+ }
+
+ try {
+ new non_pod[magic_allocation_size];
+ abort ();
+ } catch (exc &) {
+ }
+
+ return 0;
+}

180
gcc47-pr55137.patch Normal file
View File

@ -0,0 +1,180 @@
2012-11-07 Jakub Jelinek <jakub@redhat.com>
PR c++/55137
* fold-const.c (fold_binary_loc) <associate>: Don't introduce
TREE_OVERFLOW through reassociation. If type doesn't have defined
overflow, but one or both of the operands do, use the wrapping type
for reassociation and only convert to type at the end.
* g++.dg/opt/pr55137.C: New test.
* gcc.c-torture/execute/pr55137.c: New test.
--- gcc/fold-const.c.jj 2012-11-07 09:16:41.929494183 +0100
+++ gcc/fold-const.c 2012-11-07 09:47:12.227710542 +0100
@@ -10309,6 +10309,7 @@ fold_binary_loc (location_t loc,
{
tree var0, con0, lit0, minus_lit0;
tree var1, con1, lit1, minus_lit1;
+ tree atype = type;
bool ok = true;
/* Split both trees into variables, constants, and literals. Then
@@ -10324,11 +10325,25 @@ fold_binary_loc (location_t loc,
if (code == MINUS_EXPR)
code = PLUS_EXPR;
- /* With undefined overflow we can only associate constants with one
- variable, and constants whose association doesn't overflow. */
+ /* With undefined overflow prefer doing association in a type
+ which wraps on overflow, if that is one of the operand types. */
if ((POINTER_TYPE_P (type) && POINTER_TYPE_OVERFLOW_UNDEFINED)
|| (INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type)))
{
+ if (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
+ && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)))
+ atype = TREE_TYPE (arg0);
+ else if (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
+ && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1)))
+ atype = TREE_TYPE (arg1);
+ gcc_assert (TYPE_PRECISION (atype) == TYPE_PRECISION (type));
+ }
+
+ /* With undefined overflow we can only associate constants with one
+ variable, and constants whose association doesn't overflow. */
+ if ((POINTER_TYPE_P (atype) && POINTER_TYPE_OVERFLOW_UNDEFINED)
+ || (INTEGRAL_TYPE_P (atype) && !TYPE_OVERFLOW_WRAPS (atype)))
+ {
if (var0 && var1)
{
tree tmp0 = var0;
@@ -10343,16 +10358,6 @@ fold_binary_loc (location_t loc,
if (!operand_equal_p (tmp0, tmp1, 0))
ok = false;
}
-
- if (ok && lit0 && lit1)
- {
- tree tmp0 = fold_convert (type, lit0);
- tree tmp1 = fold_convert (type, lit1);
-
- if (!TREE_OVERFLOW (tmp0) && !TREE_OVERFLOW (tmp1)
- && TREE_OVERFLOW (fold_build2 (code, type, tmp0, tmp1)))
- ok = false;
- }
}
/* Only do something if we found more than two objects. Otherwise,
@@ -10363,10 +10368,16 @@ fold_binary_loc (location_t loc,
+ (lit0 != 0) + (lit1 != 0)
+ (minus_lit0 != 0) + (minus_lit1 != 0))))
{
- var0 = associate_trees (loc, var0, var1, code, type);
- con0 = associate_trees (loc, con0, con1, code, type);
- lit0 = associate_trees (loc, lit0, lit1, code, type);
- minus_lit0 = associate_trees (loc, minus_lit0, minus_lit1, code, type);
+ bool any_overflows = false;
+ if (lit0) any_overflows |= TREE_OVERFLOW (lit0);
+ if (lit1) any_overflows |= TREE_OVERFLOW (lit1);
+ if (minus_lit0) any_overflows |= TREE_OVERFLOW (minus_lit0);
+ if (minus_lit1) any_overflows |= TREE_OVERFLOW (minus_lit1);
+ var0 = associate_trees (loc, var0, var1, code, atype);
+ con0 = associate_trees (loc, con0, con1, code, atype);
+ lit0 = associate_trees (loc, lit0, lit1, code, atype);
+ minus_lit0 = associate_trees (loc, minus_lit0, minus_lit1,
+ code, atype);
/* Preserve the MINUS_EXPR if the negative part of the literal is
greater than the positive part. Otherwise, the multiplicative
@@ -10380,38 +10391,45 @@ fold_binary_loc (location_t loc,
&& tree_int_cst_lt (lit0, minus_lit0))
{
minus_lit0 = associate_trees (loc, minus_lit0, lit0,
- MINUS_EXPR, type);
+ MINUS_EXPR, atype);
lit0 = 0;
}
else
{
lit0 = associate_trees (loc, lit0, minus_lit0,
- MINUS_EXPR, type);
+ MINUS_EXPR, atype);
minus_lit0 = 0;
}
}
+
+ /* Don't introduce overflows through reassociation. */
+ if (!any_overflows
+ && ((lit0 && TREE_OVERFLOW (lit0))
+ || (minus_lit0 && TREE_OVERFLOW (minus_lit0))))
+ return NULL_TREE;
+
if (minus_lit0)
{
if (con0 == 0)
return
fold_convert_loc (loc, type,
associate_trees (loc, var0, minus_lit0,
- MINUS_EXPR, type));
+ MINUS_EXPR, atype));
else
{
con0 = associate_trees (loc, con0, minus_lit0,
- MINUS_EXPR, type);
+ MINUS_EXPR, atype);
return
fold_convert_loc (loc, type,
associate_trees (loc, var0, con0,
- PLUS_EXPR, type));
+ PLUS_EXPR, atype));
}
}
- con0 = associate_trees (loc, con0, lit0, code, type);
+ con0 = associate_trees (loc, con0, lit0, code, atype);
return
fold_convert_loc (loc, type, associate_trees (loc, var0, con0,
- code, type));
+ code, atype));
}
}
--- gcc/testsuite/g++.dg/opt/pr55137.C.jj 2012-11-07 09:31:45.027160654 +0100
+++ gcc/testsuite/g++.dg/opt/pr55137.C 2012-11-07 09:31:45.028160649 +0100
@@ -0,0 +1,4 @@
+// PR c++/55137
+// { dg-do compile }
+
+enum E { F = -1 + (int) (sizeof (int) - 1) };
--- gcc/testsuite/gcc.c-torture/execute/pr55137.c.jj 2012-11-07 09:44:11.226768063 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr55137.c 2012-11-07 09:44:24.380691303 +0100
@@ -0,0 +1,30 @@
+/* PR c++/55137 */
+
+extern void abort (void);
+
+int
+foo (unsigned int x)
+{
+ return ((int) (x + 1U) + 1) < (int) x;
+}
+
+int
+bar (unsigned int x)
+{
+ return (int) (x + 1U) + 1;
+}
+
+int
+baz (unsigned int x)
+{
+ return x + 1U;
+}
+
+int
+main ()
+{
+ if (foo (__INT_MAX__) != (bar (__INT_MAX__) < __INT_MAX__)
+ || foo (__INT_MAX__) != ((int) baz (__INT_MAX__) + 1 < __INT_MAX__))
+ abort ();
+ return 0;
+}

62
gcc47-pr55236.patch Normal file
View File

@ -0,0 +1,62 @@
2012-11-08 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/55236
* fold-const.c (make_range_step) <case NEGATE_EXPR>: For -fwrapv
and signed ARG0_TYPE, force low and high to be non-NULL.
* gcc.dg/pr55236.c: New test.
--- gcc/fold-const.c.jj 2012-11-07 11:24:34.000000000 +0100
+++ gcc/fold-const.c 2012-11-08 16:54:38.978339040 +0100
@@ -3880,6 +3880,17 @@ make_range_step (location_t loc, enum tr
return arg0;
case NEGATE_EXPR:
+ /* If flag_wrapv and ARG0_TYPE is signed, make sure
+ low and high are non-NULL, then normalize will DTRT. */
+ if (!TYPE_UNSIGNED (arg0_type)
+ && !TYPE_OVERFLOW_UNDEFINED (arg0_type))
+ {
+ if (low == NULL_TREE)
+ low = TYPE_MIN_VALUE (arg0_type);
+ if (high == NULL_TREE)
+ high = TYPE_MAX_VALUE (arg0_type);
+ }
+
/* (-x) IN [a,b] -> x in [-b, -a] */
n_low = range_binop (MINUS_EXPR, exp_type,
build_int_cst (exp_type, 0),
--- gcc/testsuite/gcc.dg/pr55236.c.jj 2012-11-08 16:40:49.171781137 +0100
+++ gcc/testsuite/gcc.dg/pr55236.c 2012-11-08 16:41:20.044578919 +0100
@@ -0,0 +1,31 @@
+/* PR tree-optimization/55236 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fwrapv" } */
+
+extern void abort ();
+
+__attribute__((noinline, noclone)) void
+foo (int i)
+{
+ if (i > 0)
+ abort ();
+ i = -i;
+ if (i < 0)
+ return;
+ abort ();
+}
+
+__attribute__((noinline, noclone)) void
+bar (int i)
+{
+ if (i > 0 || (-i) >= 0)
+ abort ();
+}
+
+int
+main ()
+{
+ foo (-__INT_MAX__ - 1);
+ bar (-__INT_MAX__ - 1);
+ return 0;
+}

View File

@ -1,2 +1,2 @@
2659f09c2e43ef8b7d4406321753f1b2 fastjar-0.97.tar.gz
7d9235cf09e4c74dfcda089836d26c2e gcc-4.7.2-20121105.tar.bz2
2136a229e204d8a4425e21034e56c706 gcc-4.7.2-20121109.tar.bz2