Hi!

I've backported a bunch of patches from trunk to 4.7, after
bootstrapping/regtesting them on x86_64-linux and i686-linux.

        Jakub
2013-02-19  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2012-11-27  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/55110
        * tree-vect-loop.c (vectorizable_reduction): Don't assert
        that STMT_VINFO_RELATED_STMT of orig_stmt is stmt.

        * gcc.dg/pr55110.c: New test.

--- gcc/tree-vect-loop.c        (revision 193844)
+++ gcc/tree-vect-loop.c        (revision 193845)
@@ -4624,7 +4624,6 @@ vectorizable_reduction (gimple stmt, gim
   if (orig_stmt)
     {
       orig_stmt_info = vinfo_for_stmt (orig_stmt);
-      gcc_assert (STMT_VINFO_RELATED_STMT (orig_stmt_info) == stmt);
       gcc_assert (STMT_VINFO_IN_PATTERN_P (orig_stmt_info));
       gcc_assert (!STMT_VINFO_IN_PATTERN_P (stmt_info));
     }
--- gcc/testsuite/gcc.dg/pr55110.c      (revision 0)
+++ gcc/testsuite/gcc.dg/pr55110.c      (revision 193845)
@@ -0,0 +1,13 @@
+/* PR tree-optimization/55110 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -ftree-vectorize" } */
+
+int
+foo (int x)
+{
+  int a, b;
+  for (b = 0; b < 8; b++)
+    for (a = 0; a < 2; a++)
+      x /= 3;
+  return x;
+}
2013-02-19  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-02-06  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/56217
        * omp-low.c (use_pointer_for_field): Return false if
        lower_send_shared_vars doesn't generate any copy-out code.

        * g++.dg/gomp/pr56217.C: New test.

        * testsuite/libgomp.c++/pr56217.C: New test.

--- gcc/omp-low.c       (revision 195795)
+++ gcc/omp-low.c       (revision 195796)
@@ -757,12 +757,20 @@ use_pointer_for_field (tree decl, omp_co
       if (TREE_ADDRESSABLE (decl))
        return true;
 
+      /* lower_send_shared_vars only uses copy-in, but not copy-out
+        for these.  */
+      if (TREE_READONLY (decl)
+         || ((TREE_CODE (decl) == RESULT_DECL
+              || TREE_CODE (decl) == PARM_DECL)
+             && DECL_BY_REFERENCE (decl)))
+       return false;
+
       /* Disallow copy-in/out in nested parallel if
         decl is shared in outer parallel, otherwise
         each thread could store the shared variable
         in its own copy-in location, making the
         variable no longer really shared.  */
-      if (!TREE_READONLY (decl) && shared_ctx->is_nested)
+      if (shared_ctx->is_nested)
        {
          omp_context *up;
 
@@ -785,11 +793,10 @@ use_pointer_for_field (tree decl, omp_co
            }
        }
 
-      /* For tasks avoid using copy-in/out, unless they are readonly
-        (in which case just copy-in is used).  As tasks can be
+      /* For tasks avoid using copy-in/out.  As tasks can be
         deferred or executed in different thread, when GOMP_task
         returns, the task hasn't necessarily terminated.  */
-      if (!TREE_READONLY (decl) && is_task_ctx (shared_ctx))
+      if (is_task_ctx (shared_ctx))
        {
          tree outer;
        maybe_mark_addressable_and_ret:
--- gcc/testsuite/g++.dg/gomp/pr56217.C (revision 0)
+++ gcc/testsuite/g++.dg/gomp/pr56217.C (revision 195796)
@@ -0,0 +1,14 @@
+// PR middle-end/56217
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+struct S { int *p; S (); S (S &); };
+
+S
+foo ()
+{
+  S s;
+  #pragma omp task shared (s)
+    s.p = 0;
+  return s;
+}
--- libgomp/testsuite/libgomp.c++/pr56217.C     (revision 0)
+++ libgomp/testsuite/libgomp.c++/pr56217.C     (revision 195796)
@@ -0,0 +1,36 @@
+// PR middle-end/56217
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+extern "C" void abort ();
+
+template <typename T>
+struct ptr {
+  T *p;
+  ptr () : p () {}
+  ptr (ptr &) = delete;
+  ptr (ptr &&o) : p(o) {}
+  operator T * () { return p; }
+};
+
+int a[6] = { 100, 101, 102, 103, 104, 105 };
+
+static ptr<int>
+f ()
+{
+  ptr<int> pt;
+  #pragma omp task shared (pt)
+    pt.p = a + 2;
+  #pragma omp taskwait
+  return pt;
+}
+
+int
+main ()
+{
+  ptr<int> pt;
+  #pragma omp parallel
+  #pragma omp single
+  if (f () != a + 2 || *f () != 102)
+    abort ();
+}
2013-02-19  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-02-07  Jakub Jelinek  <ja...@redhat.com>

        PR c++/56237
        * decl.c (push_local_name): Look at DECL_DISCRIMINATOR (t)
        only if DECL_DISCRIMINATOR_SET_P (t) rather than just
        DECL_LANG_SPECIFIC (t).

        * g++.dg/abi/mangle61.C: New test.

--- gcc/cp/decl.c       (revision 195857)
+++ gcc/cp/decl.c       (revision 195858)
@@ -920,7 +920,7 @@ push_local_name (tree decl)
          if (!DECL_LANG_SPECIFIC (decl))
            retrofit_lang_decl (decl);
          DECL_LANG_SPECIFIC (decl)->u.base.u2sel = 1;
-         if (DECL_LANG_SPECIFIC (t))
+         if (DECL_DISCRIMINATOR_SET_P (t))
            DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1;
          else
            DECL_DISCRIMINATOR (decl) = 1;
--- gcc/testsuite/g++.dg/abi/mangle61.C (revision 0)
+++ gcc/testsuite/g++.dg/abi/mangle61.C (revision 195858)
@@ -0,0 +1,28 @@
+// PR c++/56237
+// { dg-do compile }
+
+void *p[4];
+
+void
+foo ()
+{
+  static union { } u;
+  p[0] = &u;
+  {
+    static union { } u; 
+    p[1] = &u;
+    {
+      static union { } u;
+      p[2] = &u;
+    }
+  }
+  {
+    static union { } u;
+    p[3] = &u;
+  }
+}
+
+// { dg-final { scan-assembler "_ZZ3foovE1u\[^_\]" } }
+// { dg-final { scan-assembler "_ZZ3foovE1u_0" } }
+// { dg-final { scan-assembler "_ZZ3foovE1u_1" } }
+// { dg-final { scan-assembler "_ZZ3foovE1u_2" } }
2013-02-19  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-02-07  Jakub Jelinek  <ja...@redhat.com>
 
        PR c++/56239
        * parser.c (cp_parser_token_starts_cast_expression): Renamed to...
        (cp_parser_tokens_start_cast_expression): ... this.  Change parameter
        to cp_parser *, call cp_lexer_peek_token first.  For CPP_OPEN_PAREN,
        return true only if 2nd token isn't CPP_CLOSE_PAREN.
        (cp_parser_cast_expression): Adjust caller.

        * g++.dg/parse/pr56239.C: New test.

--- gcc/cp/parser.c     (revision 195858)
+++ gcc/cp/parser.c     (revision 195859)
@@ -7091,8 +7091,9 @@ cp_parser_delete_expression (cp_parser*
    otherwise.  */
 
 static bool
-cp_parser_token_starts_cast_expression (cp_token *token)
+cp_parser_tokens_start_cast_expression (cp_parser *parser)
 {
+  cp_token *token = cp_lexer_peek_token (parser->lexer);
   switch (token->type)
     {
     case CPP_COMMA:
@@ -7133,6 +7134,12 @@ cp_parser_token_starts_cast_expression (
     case CPP_EOF:
       return false;
 
+    case CPP_OPEN_PAREN:
+      /* In ((type ()) () the last () isn't a valid cast-expression,
+        so the whole must be parsed as postfix-expression.  */
+      return cp_lexer_peek_nth_token (parser->lexer, 2)->type
+            != CPP_CLOSE_PAREN;
+
       /* '[' may start a primary-expression in obj-c++.  */
     case CPP_OPEN_SQUARE:
       return c_dialect_objc ();
@@ -7225,8 +7232,7 @@ cp_parser_cast_expression (cp_parser *pa
         parenthesized ctor such as `(T ())' that looks like a cast to
         function returning T.  */
       if (!cp_parser_error_occurred (parser)
-         && cp_parser_token_starts_cast_expression (cp_lexer_peek_token
-                                                    (parser->lexer)))
+         && cp_parser_tokens_start_cast_expression (parser))
        {
          cp_parser_parse_definitely (parser);
          expr = cp_parser_cast_expression (parser,
--- gcc/testsuite/g++.dg/parse/pr56239.C        (revision 0)
+++ gcc/testsuite/g++.dg/parse/pr56239.C        (revision 195859)
@@ -0,0 +1,13 @@
+// PR c++/56239
+// { dg-do compile }
+
+struct S
+{
+  int operator () () { return 0; }
+};
+
+int
+main ()
+{
+  return (S ()) ();
+}
2013-02-19  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-02-07  Jakub Jelinek  <ja...@redhat.com>

        PR c++/56241
        * init.c (build_vec_init): Don't append NULL values into new_vec.
        (build_zero_init_1): Don't push anything into v if recursive call
        returned NULL_TREE.
        (build_value_init_noctor): Don't push anything into v if
        build_value_init call returned NULL_TREE.

        * g++.dg/parse/crash61.C: New test.

--- gcc/cp/init.c       (revision 195865)
+++ gcc/cp/init.c       (revision 195866)
@@ -254,21 +254,23 @@ build_zero_init_1 (tree type, tree nelts
         have an upper bound of -1.  */
       if (!tree_int_cst_equal (max_index, integer_minus_one_node))
        {
-         constructor_elt *ce;
-
-         v = VEC_alloc (constructor_elt, gc, 1);
-         ce = VEC_quick_push (constructor_elt, v, NULL);
+         constructor_elt ce;
 
          /* If this is a one element array, we just use a regular init.  */
          if (tree_int_cst_equal (size_zero_node, max_index))
-           ce->index = size_zero_node;
+           ce.index = size_zero_node;
          else
-           ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node,
-                               max_index);
+           ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node,
+                              max_index);
 
-         ce->value = build_zero_init_1 (TREE_TYPE (type),
-                                        /*nelts=*/NULL_TREE,
-                                        static_storage_p, NULL_TREE);
+         ce.value = build_zero_init_1 (TREE_TYPE (type),
+                                       /*nelts=*/NULL_TREE,
+                                       static_storage_p, NULL_TREE);
+         if (ce.value)
+           {
+             v = VEC_alloc (constructor_elt, gc, 1);
+             *VEC_quick_push (constructor_elt, v, NULL) = ce;
+           }
        }
 
       /* Build a constructor to contain the initializations.  */
@@ -449,28 +451,31 @@ build_value_init_noctor (tree type, tsub
         have an upper bound of -1.  */
       if (!tree_int_cst_equal (max_index, integer_minus_one_node))
        {
-         constructor_elt *ce;
-
-         v = VEC_alloc (constructor_elt, gc, 1);
-         ce = VEC_quick_push (constructor_elt, v, NULL);
+         constructor_elt ce;
 
          /* If this is a one element array, we just use a regular init.  */
          if (tree_int_cst_equal (size_zero_node, max_index))
-           ce->index = size_zero_node;
+           ce.index = size_zero_node;
          else
-           ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node,
-                               max_index);
+           ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node,
+                              max_index);
 
-         ce->value = build_value_init (TREE_TYPE (type), complain);
+         ce.value = build_value_init (TREE_TYPE (type), complain);
 
-         if (ce->value == error_mark_node)
-           return error_mark_node;
+         if (ce.value)
+           {
+             if (ce.value == error_mark_node)
+               return error_mark_node;
+
+             v = VEC_alloc (constructor_elt, gc, 1);
+             *VEC_quick_push (constructor_elt, v, NULL) = ce;
 
-         /* We shouldn't have gotten here for anything that would need
-            non-trivial initialization, and gimplify_init_ctor_preeval
-            would need to be fixed to allow it.  */
-         gcc_assert (TREE_CODE (ce->value) != TARGET_EXPR
-                     && TREE_CODE (ce->value) != AGGR_INIT_EXPR);
+             /* We shouldn't have gotten here for anything that would need
+                non-trivial initialization, and gimplify_init_ctor_preeval
+                would need to be fixed to allow it.  */
+             gcc_assert (TREE_CODE (ce.value) != TARGET_EXPR
+                         && TREE_CODE (ce.value) != AGGR_INIT_EXPR);
+           }
        }
 
       /* Build a constructor to contain the initializations.  */
@@ -3335,9 +3340,12 @@ build_vec_init (tree base, tree maxindex
              else
                {
                  if (do_static_init)
-                   CONSTRUCTOR_APPEND_ELT (new_vec, field,
-                                           build_zero_init (TREE_TYPE (e),
-                                                            NULL_TREE, true));
+                   {
+                     tree value = build_zero_init (TREE_TYPE (e), NULL_TREE,
+                                                   true);
+                     if (value)
+                       CONSTRUCTOR_APPEND_ELT (new_vec, field, value);
+                   }
                  saw_non_const = true;
                }
            }
--- gcc/testsuite/g++.dg/parse/crash61.C        (revision 0)
+++ gcc/testsuite/g++.dg/parse/crash61.C        (revision 195866)
@@ -0,0 +1,6 @@
+// PR c++/56241
+// { dg-do compile }
+
+struct pair { constexpr pair (const) : }; // { dg-error "" }
+template <0> make_pair () {}             // { dg-error "" }
+pair prefix[] = { 0, make_pair }         // { dg-error "" }
2013-02-19  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-02-08  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/56250
        * fold-const.c (extract_muldiv_1) <case NEGATE_EXPR>: Don't optimize
        if type is unsigned and code isn't MULT_EXPR.

        * gcc.c-torture/execute/pr56250.c: New test.

--- gcc/fold-const.c    (revision 195887)
+++ gcc/fold-const.c    (revision 195888)
@@ -5695,6 +5695,11 @@ extract_muldiv_1 (tree t, tree c, enum t
         break;
       /* FALLTHROUGH */
     case NEGATE_EXPR:
+      /* For division and modulus, type can't be unsigned, as e.g.
+        (-(x / 2U)) / 2U isn't equal to -((x / 2U) / 2U) for x >= 2.
+        For signed types, even with wrapping overflow, this is fine.  */
+      if (code != MULT_EXPR && TYPE_UNSIGNED (type))
+       break;
       if ((t1 = extract_muldiv (op0, c, code, wide_type, strict_overflow_p))
          != 0)
        return fold_build1 (tcode, ctype, fold_convert (ctype, t1));
--- gcc/testsuite/gcc.c-torture/execute/pr56250.c       (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr56250.c       (revision 195888)
@@ -0,0 +1,13 @@
+/* PR tree-optimization/56250 */
+
+extern void abort (void);
+
+int
+main ()
+{
+  unsigned int x = 2;
+  unsigned int y = (0U - x / 2) / 2;
+  if (-1U / x != y)
+    abort ();
+  return 0;
+}
2013-02-19  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-02-09  Jakub Jelinek  <ja...@redhat.com>

        PR other/56245
        * regex.c (PTR_INT_TYPE): Define.
        (EXTEND_BUFFER): Change incr type from int to PTR_INT_TYPE.

--- libiberty/regex.c   (revision 195917)
+++ libiberty/regex.c   (revision 195918)
@@ -46,9 +46,11 @@
 
 # if defined STDC_HEADERS && !defined emacs
 #  include <stddef.h>
+#  define PTR_INT_TYPE ptrdiff_t
 # else
 /* We need this for `regex.h', and perhaps for the Emacs include files.  */
 #  include <sys/types.h>
+#  define PTR_INT_TYPE long
 # endif
 
 # define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC)
@@ -2045,7 +2047,7 @@ static reg_errcode_t byte_compile_range
     /* How many characters the new buffer can have?  */                        
\
     wchar_count = bufp->allocated / sizeof(UCHAR_T);                   \
     if (wchar_count == 0) wchar_count = 1;                             \
-    /* Truncate the buffer to CHAR_T align.  */                        \
+    /* Truncate the buffer to CHAR_T align.  */                                
\
     bufp->allocated = wchar_count * sizeof(UCHAR_T);                   \
     RETALLOC (COMPILED_BUFFER_VAR, wchar_count, UCHAR_T);              \
     bufp->buffer = (char*)COMPILED_BUFFER_VAR;                         \
@@ -2054,7 +2056,7 @@ static reg_errcode_t byte_compile_range
     /* If the buffer moved, move all the pointers into it.  */         \
     if (old_buffer != COMPILED_BUFFER_VAR)                             \
       {                                                                        
\
-       int incr = COMPILED_BUFFER_VAR - old_buffer;                    \
+       PTR_INT_TYPE incr = COMPILED_BUFFER_VAR - old_buffer;           \
        MOVE_BUFFER_POINTER (b);                                        \
        MOVE_BUFFER_POINTER (begalt);                                   \
        if (fixup_alt_jump)                                             \
@@ -2082,7 +2084,7 @@ static reg_errcode_t byte_compile_range
     /* If the buffer moved, move all the pointers into it.  */         \
     if (old_buffer != COMPILED_BUFFER_VAR)                             \
       {                                                                        
\
-       int incr = COMPILED_BUFFER_VAR - old_buffer;                    \
+       PTR_INT_TYPE incr = COMPILED_BUFFER_VAR - old_buffer;           \
        MOVE_BUFFER_POINTER (b);                                        \
        MOVE_BUFFER_POINTER (begalt);                                   \
        if (fixup_alt_jump)                                             \
2013-02-19  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-02-19  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/56381
        * tree-ssa-pre.c (create_expression_by_pieces): Fix up last argument
        to fold_build3.

--- gcc/tree-ssa-pre.c  (revision 196132)
+++ gcc/tree-ssa-pre.c  (revision 196133)
@@ -2923,7 +2923,7 @@ create_expression_by_pieces (basic_block
                break;
              case 3:
                folded = fold_build3 (nary->opcode, nary->type,
-                                     genop[0], genop[1], genop[3]);
+                                     genop[0], genop[1], genop[2]);
                break;
              default:
                gcc_unreachable ();
2013-02-19  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2013-02-19  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/56350
        * tree-vect-loop.c (vectorizable_reduction): If orig_stmt, return false
        if haven't found reduction or nested cycle operand, rather than
        asserting we must find it.

        * gcc.dg/pr56350.c: New test.

--- gcc/tree-vect-loop.c        (revision 196133)
+++ gcc/tree-vect-loop.c        (revision 196134)
@@ -4707,7 +4707,7 @@ vectorizable_reduction (gimple stmt, gim
      The last use is the reduction variable.  In case of nested cycle this
      assumption is not true: we use reduc_index to record the index of the
      reduction variable.  */
-  for (i = 0; i < op_type-1; i++)
+  for (i = 0; i < op_type - 1; i++)
     {
       /* The condition of COND_EXPR is checked in vectorizable_condition().  */
       if (i == 0 && code == COND_EXPR)
@@ -4739,11 +4739,18 @@ vectorizable_reduction (gimple stmt, gim
   if (!vectype_in)
     vectype_in = tem;
   gcc_assert (is_simple_use);
-  gcc_assert (dt == vect_reduction_def
-              || dt == vect_nested_cycle
-              || ((dt == vect_internal_def || dt == vect_external_def
-                   || dt == vect_constant_def || dt == vect_induction_def)
-                   && nested_cycle && found_nested_cycle_def));
+  if (!(dt == vect_reduction_def
+       || dt == vect_nested_cycle
+       || ((dt == vect_internal_def || dt == vect_external_def
+            || dt == vect_constant_def || dt == vect_induction_def)
+           && nested_cycle && found_nested_cycle_def)))
+    {
+      /* For pattern recognized stmts, orig_stmt might be a reduction,
+        but some helper statements for the pattern might not, or
+        might be COND_EXPRs with reduction uses in the condition.  */
+      gcc_assert (orig_stmt);
+      return false;
+    }
   if (!found_nested_cycle_def)
     reduc_def_stmt = def_stmt;
 
--- gcc/testsuite/gcc.dg/pr56350.c      (revision 0)
+++ gcc/testsuite/gcc.dg/pr56350.c      (revision 196134)
@@ -0,0 +1,13 @@
+/* PR tree-optimization/56350 */
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-vectorize" } */
+
+int a, b, c;
+
+void
+f (void)
+{
+  for (; c; c++)
+    for (b = 0; b < 2; b++)
+      a /= 8;
+}

Reply via email to