Hi!

I've backported a few bugfixes to 4.8 branch, bootstrapped/regtested on
x86_64-linux and i686-linux, committed to branch.

        Jakub
2014-03-06  Jakub Jelinek  <ja...@redhat.com>

        PR preprocessor/60400
        Backport from mainline
        2013-06-24  Dehao Chen  <de...@google.com>

        * files.c (_cpp_stack_include): Fix the highest_location when header
        file is guarded by #ifndef and is included twice.

        2014-03-03  Jakub Jelinek  <ja...@redhat.com>

        PR preprocessor/60400
        * c-c++-common/cpp/pr60400.c: New test.
        * c-c++-common/cpp/pr60400-1.h: New file.
        * c-c++-common/cpp/pr60400-2.h: New file.

--- libcpp/files.c      (revision 200375)
+++ libcpp/files.c      (revision 200376)
@@ -983,6 +983,7 @@ _cpp_stack_include (cpp_reader *pfile, c
 {
   struct cpp_dir *dir;
   _cpp_file *file;
+  bool stacked;
 
   dir = search_path_head (pfile, fname, angle_brackets, type);
   if (!dir)
@@ -993,19 +994,26 @@ _cpp_stack_include (cpp_reader *pfile, c
   if (type == IT_DEFAULT && file == NULL)
     return false;
 
-  /* Compensate for the increment in linemap_add that occurs in
-     _cpp_stack_file.  In the case of a normal #include, we're
-     currently at the start of the line *following* the #include.  A
-     separate source_location for this location makes no sense (until
-     we do the LC_LEAVE), and complicates LAST_SOURCE_LINE_LOCATION.
-     This does not apply if we found a PCH file (in which case
-     linemap_add is not called) or we were included from the
-     command-line.  */
+  /* Compensate for the increment in linemap_add that occurs if
+      _cpp_stack_file actually stacks the file.  In the case of a
+     normal #include, we're currently at the start of the line
+     *following* the #include.  A separate source_location for this
+     location makes no sense (until we do the LC_LEAVE), and
+     complicates LAST_SOURCE_LINE_LOCATION.  This does not apply if we
+     found a PCH file (in which case linemap_add is not called) or we
+     were included from the command-line.  */
   if (file->pchname == NULL && file->err_no == 0
       && type != IT_CMDLINE && type != IT_DEFAULT)
     pfile->line_table->highest_location--;
 
-  return _cpp_stack_file (pfile, file, type == IT_IMPORT);
+  stacked = _cpp_stack_file (pfile, file, type == IT_IMPORT);
+
+  if (!stacked)
+    /* _cpp_stack_file didn't stack the file, so let's rollback the
+       compensation dance we performed above.  */
+    pfile->line_table->highest_location++;
+
+  return stacked;
 }
 
 /* Could not open FILE.  The complication is dependency output.  */
--- gcc/testsuite/c-c++-common/cpp/pr60400.c    (revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr60400.c    (revision 208272)
@@ -0,0 +1,13 @@
+/* PR preprocessor/60400 */
+/* { dg-do compile } */
+/* { dg-options "-trigraphs -Wtrigraphs" } */
+
+??=include "pr60400-1.h"
+??=include "pr60400-2.h"
+
+/* { dg-warning "trigraph" "" { target *-*-* } 1 } */
+/* { dg-warning "trigraph" "" { target *-*-* } 2 } */
+/* { dg-warning "trigraph" "" { target *-*-* } 3 } */
+/* { dg-warning "trigraph" "" { target *-*-* } 4 } */
+/* { dg-warning "trigraph" "" { target *-*-* } 5 } */
+/* { dg-warning "trigraph" "" { target *-*-* } 6 } */
--- gcc/testsuite/c-c++-common/cpp/pr60400-1.h  (revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr60400-1.h  (revision 208272)
@@ -0,0 +1,3 @@
+??=ifndef PR60400_1_H
+??=define PR60400_1_H
+??=endif
--- gcc/testsuite/c-c++-common/cpp/pr60400-2.h  (revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr60400-2.h  (revision 208272)
@@ -0,0 +1,4 @@
+??=ifndef PR60400_2_H
+??=define PR60400_2_H
+??=include "pr60400-1.h"
+??=endif
2014-03-06  Jakub Jelinek  <ja...@redhat.com>

        Backport from mainline
        2014-02-05  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/57499
        * tree-eh.c (cleanup_empty_eh): Bail out on totally empty
        bb with no successors.

        * g++.dg/torture/pr57499.C: New test.

--- gcc/tree-eh.c       (revision 207503)
+++ gcc/tree-eh.c       (revision 207504)
@@ -4396,8 +4396,11 @@ cleanup_empty_eh (eh_landing_pad lp)
   /* If the block is totally empty, look for more unsplitting cases.  */
   if (gsi_end_p (gsi))
     {
-      /* For the degenerate case of an infinite loop bail out.  */
-      if (infinite_empty_loop_p (e_out))
+      /* For the degenerate case of an infinite loop bail out.
+        If bb has no successors and is totally empty, which can happen e.g.
+        because of incorrect noreturn attribute, bail out too.  */
+      if (e_out == NULL
+         || infinite_empty_loop_p (e_out))
        return ret;
 
       return ret | cleanup_empty_eh_unsplit (bb, e_out, lp);
--- gcc/testsuite/g++.dg/torture/pr57499.C      (revision 0)
+++ gcc/testsuite/g++.dg/torture/pr57499.C      (revision 207504)
@@ -0,0 +1,14 @@
+// PR middle-end/57499
+// { dg-do compile }
+
+struct S
+{
+  ~S () __attribute__ ((noreturn)) {} // { dg-warning "function does return" }
+};
+
+void
+foo ()
+{
+  S s;
+  throw 1;
+}
2014-03-06  Jakub Jelinek  <ja...@redhat.com>

        Backport from mainline
        2014-02-07  Jakub Jelinek  <ja...@redhat.com>

        PR preprocessor/56824
        * line-map.c (linemap_compare_locations): Look through adhoc locations
        for both l0 and l1.

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

--- libcpp/line-map.c   (revision 207605)
+++ libcpp/line-map.c   (revision 207606)
@@ -1024,6 +1024,11 @@ linemap_compare_locations (struct line_m
   bool pre_virtual_p, post_virtual_p;
   source_location l0 = pre, l1 = post;
 
+  if (IS_ADHOC_LOC (l0))
+    l0 = set->location_adhoc_data_map.data[l0 & MAX_SOURCE_LOCATION].locus;
+  if (IS_ADHOC_LOC (l1))
+    l1 = set->location_adhoc_data_map.data[l1 & MAX_SOURCE_LOCATION].locus;
+
   if (l0 == l1)
     return 0;
 
--- gcc/testsuite/gcc.dg/pr56824.c      (revision 0)
+++ gcc/testsuite/gcc.dg/pr56824.c      (revision 207606)
@@ -0,0 +1,18 @@
+/* PR preprocessor/56824 */
+/* { dg-do compile } */
+/* { dg-options "-Waggregate-return" } */
+
+struct S { int i; };
+struct S foo (void);
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Waggregate-return"
+
+int
+main ()
+{
+  foo ();
+  return 0;
+}
+
+#pragma GCC diagnostic pop
2014-03-06  Jakub Jelinek  <ja...@redhat.com>

        Backport from mainline
        2014-02-11  Richard Henderson  <r...@redhat.com>
                    Jakub Jelinek  <ja...@redhat.com>

        PR debug/59776
        * tree-sra.c (load_assign_lhs_subreplacements): Add VIEW_CONVERT_EXPR
        around drhs if type conversion to lacc->type is not useless.

        * gcc.dg/guality/pr59776.c: New test.

--- gcc/tree-sra.c      (revision 207694)
+++ gcc/tree-sra.c      (revision 207695)
@@ -2950,6 +2950,10 @@ load_assign_lhs_subreplacements (struct
                                                  lacc);
              else
                drhs = NULL_TREE;
+             if (drhs
+                 && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
+               drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
+                                       lacc->type, drhs);
              ds = gimple_build_debug_bind (get_access_replacement (lacc),
                                            drhs, gsi_stmt (*old_gsi));
              gsi_insert_after (new_gsi, ds, GSI_NEW_STMT);
--- gcc/testsuite/gcc.dg/guality/pr59776.c      (revision 0)
+++ gcc/testsuite/gcc.dg/guality/pr59776.c      (revision 207695)
@@ -0,0 +1,29 @@
+/* PR debug/59776 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+#include "../nop.h"
+
+struct S { float f, g; };
+
+__attribute__((noinline, noclone)) void
+foo (struct S *p)
+{
+  struct S s1, s2;                     /* { dg-final { gdb-test pr59776.c:17 
"s1.f" "5.0" } } */
+  s1 = *p;                             /* { dg-final { gdb-test pr59776.c:17 
"s1.g" "6.0" } } */
+  s2 = s1;                             /* { dg-final { gdb-test pr59776.c:17 
"s2.f" "0.0" } } */
+  *(int *) &s2.f = 0;                  /* { dg-final { gdb-test pr59776.c:17 
"s2.g" "6.0" } } */
+  asm volatile (NOP : : : "memory");   /* { dg-final { gdb-test pr59776.c:20 
"s1.f" "5.0" } } */
+  asm volatile (NOP : : : "memory");   /* { dg-final { gdb-test pr59776.c:20 
"s1.g" "6.0" } } */
+  s2 = s1;                             /* { dg-final { gdb-test pr59776.c:20 
"s2.f" "5.0" } } */
+  asm volatile (NOP : : : "memory");   /* { dg-final { gdb-test pr59776.c:20 
"s2.g" "6.0" } } */
+  asm volatile (NOP : : : "memory");
+}
+
+int
+main ()
+{
+  struct S x = { 5.0f, 6.0f };
+  foo (&x);
+  return 0;
+}
2014-03-06  Jakub Jelinek  <ja...@redhat.com>

        Backport from mainline
        2014-02-11  Jakub Jelinek  <ja...@redhat.com>

        PR fortran/52370
        * trans-decl.c (gfc_build_dummy_array_decl): Set TREE_NO_WARNING
        on decl if sym->attr.optional.

        * gfortran.dg/pr52370.f90: New test.

--- gcc/fortran/trans-decl.c    (revision 207697)
+++ gcc/fortran/trans-decl.c    (revision 207698)
@@ -1014,6 +1014,10 @@ gfc_build_dummy_array_decl (gfc_symbol *
   TREE_STATIC (decl) = 0;
   DECL_EXTERNAL (decl) = 0;
 
+  /* Avoid uninitialized warnings for optional dummy arguments.  */
+  if (sym->attr.optional)
+    TREE_NO_WARNING (decl) = 1;
+
   /* We should never get deferred shape arrays here.  We used to because of
      frontend bugs.  */
   gcc_assert (sym->as->type != AS_DEFERRED);
--- gcc/testsuite/gfortran.dg/pr52370.f90       (revision 0)
+++ gcc/testsuite/gfortran.dg/pr52370.f90       (revision 207698)
@@ -0,0 +1,21 @@
+! PR fortran/52370
+! { dg-do compile }
+! { dg-options "-O1 -Wall" }
+
+module pr52370
+contains
+  subroutine foo(a,b)
+    real, intent(out) :: a
+    real, dimension(:), optional, intent(out) :: b
+    a=0.5
+    if (present(b)) then
+      b=1.0
+    end if
+  end subroutine foo
+end module pr52370
+
+program prg52370
+  use pr52370
+  real :: a
+  call foo(a)
+end program prg52370
2014-03-06  Jakub Jelinek  <ja...@redhat.com>

        Backport from mainline
        2014-02-12  Jakub Jelinek  <ja...@redhat.com>

        PR c/60101
        * c-common.c (merge_tlist): If copy is true, call new_tlist,
        if false, add ADD itself, rather than vice versa.
        (verify_tree): For COND_EXPR, don't call merge_tlist with non-zero
        copy.  For SAVE_EXPR, only call merge_tlist once.

        * c-c++-common/pr60101.c: New test.

--- gcc/c-family/c-common.c     (revision 207710)
+++ gcc/c-family/c-common.c     (revision 207711)
@@ -2976,7 +2976,7 @@ merge_tlist (struct tlist **to, struct t
          }
       if (!found)
        {
-         *end = copy ? add : new_tlist (NULL, add->expr, add->writer);
+         *end = copy ? new_tlist (NULL, add->expr, add->writer) : add;
          end = &(*end)->next;
          *end = 0;
        }
@@ -3134,7 +3134,7 @@ verify_tree (tree x, struct tlist **pbef
       verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_list2, NULL_TREE);
       warn_for_collisions (tmp_list2);
       merge_tlist (pbefore_sp, tmp_before, 0);
-      merge_tlist (pbefore_sp, tmp_list2, 1);
+      merge_tlist (pbefore_sp, tmp_list2, 0);
 
       tmp_list3 = tmp_nosp = 0;
       verify_tree (TREE_OPERAND (x, 1), &tmp_list3, &tmp_nosp, NULL_TREE);
@@ -3238,12 +3238,7 @@ verify_tree (tree x, struct tlist **pbef
            warn_for_collisions (tmp_nosp);
 
            tmp_list3 = 0;
-           while (tmp_nosp)
-             {
-               struct tlist *t = tmp_nosp;
-               tmp_nosp = t->next;
-               merge_tlist (&tmp_list3, t, 0);
-             }
+           merge_tlist (&tmp_list3, tmp_nosp, 0);
            t->cache_before_sp = tmp_before;
            t->cache_after_sp = tmp_list3;
          }
--- gcc/testsuite/c-c++-common/pr60101.c        (revision 0)
+++ gcc/testsuite/c-c++-common/pr60101.c        (revision 207711)
@@ -0,0 +1,112 @@
+/* PR c/60101 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+extern int *a, b, *c, *d;
+
+void
+foo (double _Complex *x, double _Complex *y, double _Complex *z, unsigned int 
l, int w)
+{
+  unsigned int e = (unsigned int) a[3];
+  double _Complex (*v)[l][4][e][l][4] = (double _Complex (*)[l][4][e][l][4]) z;
+  double _Complex (*f)[l][b][l] = (double _Complex (*)[l][b][l]) y;
+  unsigned int g = c[0] * c[1] * c[2];
+  unsigned int h = d[0] + c[0] * (d[1] + c[1] * d[2]);
+  unsigned int i;
+
+  for (i = 0; i < e; i++)
+    {
+      int j = e * d[3] + i;
+
+      unsigned int n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11;
+      float _Complex s = 0.;
+      unsigned int t = 0;
+
+      for (n0 = 0; n0 < l; n0++)
+       for (n1 = 0; n1 < l; n1++)
+         for (n2 = 0; n2 < l; n2++)
+           for (n3 = 0; n3 < l; n3++)
+             for (n4 = 0; n4 < l; n4++)
+               for (n5 = 0; n5 < l; n5++)
+                 for (n6 = 0; n6 < l; n6++)
+                   for (n7 = 0; n7 < l; n7++)
+                     for (n8 = 0; n8 < l; n8++)
+                       for (n9 = 0; n9 < l; n9++)
+                         for (n10 = 0; n10 < l; n10++)
+                           for (n11 = 0; n11 < l; n11++)
+                             {
+                               if (t % g == h)
+                                 s
+                                   += f[n0][n4][j][n8] * f[n1][n5][j][n9] * 
~(f[n2][n6][w][n10]) * ~(f[n3][n7][w][n11])
+                                      * (+0.25 * v[0][n2][0][i][n9][1] * 
v[0][n3][0][i][n5][1] * v[0][n10][0][i][n4][1]
+                                         * v[0][n7][1][i][n8][0] * 
v[0][n11][1][i][n1][0] * v[0][n6][1][i][n0][0]
+                                         + 0.25 * v[0][n2][0][i][n9][1] * 
v[0][n3][0][i][n5][1] * v[0][n10][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+                                         - 0.5 * v[0][n2][0][i][n9][1] * 
v[0][n3][0][i][n5][1] * v[0][n10][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+                                         + 0.25 * v[0][n2][0][i][n9][1] * 
v[0][n10][0][i][n5][1] * v[0][n3][0][i][n4][1]
+                                         * v[0][n7][1][i][n8][0] * 
v[0][n6][1][i][n1][0] * v[0][n11][1][i][n0][0]
+                                         - 0.5 * v[0][n2][0][i][n9][1] * 
v[0][n10][0][i][n5][1] * v[0][n3][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+                                         + 0.25 * v[0][n2][0][i][n9][1] * 
v[0][n10][0][i][n5][1] * v[0][n3][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+                                         + 0.25 * v[0][n3][0][i][n9][1] * 
v[0][n2][0][i][n5][1] * v[0][n10][0][i][n4][1]
+                                         * v[0][n6][1][i][n8][0] * 
v[0][n11][1][i][n1][0] * v[0][n7][1][i][n0][0]
+                                         - 0.5 * v[0][n3][0][i][n9][1] * 
v[0][n2][0][i][n5][1] * v[0][n10][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+                                         + 0.25 * v[0][n3][0][i][n9][1] * 
v[0][n2][0][i][n5][1] * v[0][n10][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+                                         + 0.25 * v[0][n3][0][i][n9][1] * 
v[0][n10][0][i][n5][1] * v[0][n2][0][i][n4][1]
+                                         * v[0][n6][1][i][n8][0] * 
v[0][n7][1][i][n1][0] * v[0][n11][1][i][n0][0]
+                                         + 0.25 * v[0][n3][0][i][n9][1] * 
v[0][n10][0][i][n5][1] * v[0][n2][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+                                         - 0.5 * v[0][n3][0][i][n9][1] * 
v[0][n10][0][i][n5][1] * v[0][n2][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+                                         + 0.25 * v[0][n10][0][i][n9][1] * 
v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+                                         * v[0][n6][1][i][n8][0] * 
v[0][n7][1][i][n1][0] * v[0][n11][1][i][n0][0]
+                                         - 0.5 * v[0][n10][0][i][n9][1] * 
v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+                                         * v[0][n6][1][i][n8][0] * 
v[0][n11][1][i][n1][0] * v[0][n7][1][i][n0][0]
+                                         - 0.5 * v[0][n10][0][i][n9][1] * 
v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+                                         * v[0][n7][1][i][n8][0] * 
v[0][n6][1][i][n1][0] * v[0][n11][1][i][n0][0]
+                                         + 0.25 * v[0][n10][0][i][n9][1] * 
v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+                                         * v[0][n7][1][i][n8][0] * 
v[0][n11][1][i][n1][0] * v[0][n6][1][i][n0][0]
+                                         + 1. * v[0][n10][0][i][n9][1] * 
v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+                                         - 0.5 * v[0][n10][0][i][n9][1] * 
v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+                                         - 0.5 * v[0][n10][0][i][n9][1] * 
v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+                                         * v[0][n6][1][i][n8][0] * 
v[0][n7][1][i][n1][0] * v[0][n11][1][i][n0][0]
+                                         + 0.25 * v[0][n10][0][i][n9][1] * 
v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+                                         * v[0][n6][1][i][n8][0] * 
v[0][n11][1][i][n1][0] * v[0][n7][1][i][n0][0]
+                                         + 0.25 * v[0][n10][0][i][n9][1] * 
v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+                                         * v[0][n7][1][i][n8][0] * 
v[0][n6][1][i][n1][0] * v[0][n11][1][i][n0][0]
+                                         - 0.5 * v[0][n10][0][i][n9][1] * 
v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+                                         * v[0][n7][1][i][n8][0] * 
v[0][n11][1][i][n1][0] * v[0][n6][1][i][n0][0]
+                                         - 0.5 * v[0][n10][0][i][n9][1] * 
v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+                                         + 1. * v[0][n10][0][i][n9][1] * 
v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+                                         + 0.5 * v[0][n6][1][i][n4][1] * 
v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+                                         * v[0][n7][1][i][n1][0] * 
v[0][n11][1][i][n0][0] * v[0][n10][0][i][n8][0]
+                                         - 0.25 * v[0][n6][1][i][n4][1] * 
v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+                                         * v[0][n11][1][i][n1][0] * 
v[0][n7][1][i][n0][0] * v[0][n10][0][i][n8][0]
+                                         - 0.25 * v[0][n6][1][i][n4][1] * 
v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+                                         * v[0][n7][1][i][n8][0] * 
v[0][n11][1][i][n0][0] * v[0][n10][0][i][n1][0]
+                                         + 0.25 * v[0][n6][1][i][n4][1] * 
v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+                                         * v[0][n7][1][i][n8][0] * 
v[0][n11][1][i][n1][0] * v[0][n10][0][i][n0][0]
+                                         + 0.25 * v[0][n6][1][i][n4][1] * 
v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n7][1][i][n0][0] * v[0][n10][0][i][n1][0]
+                                         - 0.5 * v[0][n6][1][i][n4][1] * 
v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+                                         * v[0][n11][1][i][n8][0] * 
v[0][n7][1][i][n1][0] * v[0][n10][0][i][n0][0]
+                                         - 0.25 * v[0][n6][1][i][n4][1] * 
v[0][n2][0][i][n9][1] * v[0][n10][0][i][n5][1]
+                                         * v[0][n7][1][i][n1][0] * 
v[0][n11][1][i][n0][0] * v[0][n3][0][i][n8][0]
+                                         - 0.25 * v[0][n6][1][i][n4][1] * 
v[0][n2][0][i][n9][1] * v[0][n10][0][i][n5][1]
+                                         * v[0][n7][1][i][n8][0] * 
v[0][n11][1][i][n0][0] * v[0][n3][0][i][n1][0]);
+                               t++;
+                             }
+      int u = (j - w + b) % b;
+      int q = (j >= w ? +1 : -1);
+      int r = q;
+      x[u] += r * s;
+    }
+}
2014-03-06  Jakub Jelinek  <ja...@redhat.com>

        Backport from mainline
        2014-02-13  Jakub Jelinek  <ja...@redhat.com>

        PR target/43546
        * expr.c (compress_float_constant): If x is a hard register,
        extend into a pseudo and then move to x.

        * gcc.target/i386/pr43546.c: New test.

--- gcc/expr.c  (revision 207756)
+++ gcc/expr.c  (revision 207757)
@@ -3726,12 +3726,21 @@ compress_float_constant (rtx x, rtx y)
         into a new pseudo.  This constant may be used in different modes,
         and if not, combine will put things back together for us.  */
       trunc_y = force_reg (srcmode, trunc_y);
-      emit_unop_insn (ic, x, trunc_y, UNKNOWN);
+
+      /* If x is a hard register, perform the extension into a pseudo,
+        so that e.g. stack realignment code is aware of it.  */
+      rtx target = x;
+      if (REG_P (x) && HARD_REGISTER_P (x))
+       target = gen_reg_rtx (dstmode);
+
+      emit_unop_insn (ic, target, trunc_y, UNKNOWN);
       last_insn = get_last_insn ();
 
-      if (REG_P (x))
+      if (REG_P (target))
        set_unique_reg_note (last_insn, REG_EQUAL, y);
 
+      if (target != x)
+       return emit_move_insn (x, target);
       return last_insn;
     }
 
--- gcc/testsuite/gcc.target/i386/pr43546.c     (revision 0)
+++ gcc/testsuite/gcc.target/i386/pr43546.c     (revision 207757)
@@ -0,0 +1,12 @@
+/* PR target/43546 */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+/* { dg-additional-options "-mpreferred-stack-boundary=2 -msseregparm -msse" { 
target ia32 } } */
+
+extern void bar (double);
+
+void
+foo (void)
+{
+  bar (1.0);
+}
2014-03-06  Jakub Jelinek  <ja...@redhat.com>

        Backport from mainline
        2014-02-19  Jakub Jelinek  <ja...@redhat.com>

        PR preprocessor/58844
        * macro.c (enter_macro_context): Only push
        macro_real_token_count (macro) tokens rather than
        macro->count tokens, regardless of
        CPP_OPTION (pfile, track-macro-expansion).

        * c-c++-common/cpp/pr58844-1.c: New test.
        * c-c++-common/cpp/pr58844-2.c: New test.

--- libcpp/macro.c      (revision 207870)
+++ libcpp/macro.c      (revision 207871)
@@ -1115,21 +1115,22 @@ enter_macro_context (cpp_reader *pfile,
 
       if (macro->paramc == 0)
        {
+         unsigned tokens_count = macro_real_token_count (macro);
          if (CPP_OPTION (pfile, track_macro_expansion))
            {
-             unsigned int i, count = macro->count;
+             unsigned int i;
              const cpp_token *src = macro->exp.tokens;
              const struct line_map *map;
              source_location *virt_locs = NULL;
-             _cpp_buff *macro_tokens =
-               tokens_buff_new (pfile, count, &virt_locs);
+             _cpp_buff *macro_tokens
+               = tokens_buff_new (pfile, tokens_count, &virt_locs);
 
              /* Create a macro map to record the locations of the
                 tokens that are involved in the expansion. LOCATION
                 is the location of the macro expansion point.  */
-             map  = linemap_enter_macro (pfile->line_table,
-                                         node, location, count);
-             for (i = 0; i < count; ++i)
+             map = linemap_enter_macro (pfile->line_table,
+                                        node, location, tokens_count);
+             for (i = 0; i < tokens_count; ++i)
                {
                  tokens_buff_add_token (macro_tokens, virt_locs,
                                         src, src->src_loc,
@@ -1141,16 +1142,12 @@ enter_macro_context (cpp_reader *pfile,
                                            virt_locs,
                                            (const cpp_token **)
                                            macro_tokens->base,
-                                           count);
-             num_macro_tokens_counter += count;
+                                           tokens_count);
            }
          else
-           {
-             unsigned tokens_count = macro_real_token_count (macro);
-             _cpp_push_token_context (pfile, node, macro->exp.tokens,
-                                      tokens_count);
-             num_macro_tokens_counter += tokens_count;
-           }
+           _cpp_push_token_context (pfile, node, macro->exp.tokens,
+                                    tokens_count);
+         num_macro_tokens_counter += tokens_count;
        }
 
       if (pragma_buff)
--- gcc/testsuite/c-c++-common/cpp/pr58844-1.c  (revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr58844-1.c  (revision 207871)
@@ -0,0 +1,8 @@
+/* PR preprocessor/58844 */
+/* { dg-do compile } */
+/* { dg-options "-ftrack-macro-expansion=0" } */
+
+#define A x######x
+int A = 1;
+#define A x######x     /* { dg-message "previous definition" } */
+#define A x##x         /* { dg-warning "redefined" } */
--- gcc/testsuite/c-c++-common/cpp/pr58844-2.c  (revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr58844-2.c  (revision 207871)
@@ -0,0 +1,8 @@
+/* PR preprocessor/58844 */
+/* { dg-do compile } */
+/* { dg-options "-ftrack-macro-expansion=2" } */
+
+#define A x######x
+int A = 1;
+#define A x######x     /* { dg-message "previous definition" } */
+#define A x##x         /* { dg-warning "redefined" } */
2014-03-06  Jakub Jelinek  <ja...@redhat.com>

        Backport from mainline
        2014-02-19  Jakub Jelinek  <ja...@redhat.com>

        PR c/37743
        * c-common.c (c_common_nodes_and_builtins): When initializing
        c_uint{16,32,64}_type_node, also set corresponding
        uint{16,32,64}_type_node to the same value.

        * g++.dg/ext/builtin-bswap1.C: New test.
        * c-c++-common/pr37743.c: New test.

--- gcc/c-family/c-common.c     (revision 207923)
+++ gcc/c-family/c-common.c     (revision 207924)
@@ -5610,13 +5610,13 @@ c_common_nodes_and_builtins (void)
     uint8_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT8_TYPE)));
   if (UINT16_TYPE)
-    c_uint16_type_node =
+    c_uint16_type_node = uint16_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT16_TYPE)));
   if (UINT32_TYPE)
-    c_uint32_type_node =
+    c_uint32_type_node = uint32_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT32_TYPE)));
   if (UINT64_TYPE)
-    c_uint64_type_node =
+    c_uint64_type_node = uint64_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT64_TYPE)));
   if (INT_LEAST8_TYPE)
     int_least8_type_node =
--- gcc/testsuite/g++.dg/ext/builtin-bswap1.C   (revision 0)
+++ gcc/testsuite/g++.dg/ext/builtin-bswap1.C   (revision 207924)
@@ -0,0 +1,22 @@
+// PR c/37743
+// { dg-do compile }
+
+#if defined(__UINT32_TYPE__) && defined(__INT32_TYPE__)
+
+void foo (__UINT32_TYPE__);
+void foo (__INT32_TYPE__);
+
+void
+bar (__UINT32_TYPE__ x)
+{
+  foo (__builtin_bswap32 (x));
+}
+
+#else
+
+void
+bar ()
+{
+}
+
+#endif
--- gcc/testsuite/c-c++-common/pr37743.c        (revision 0)
+++ gcc/testsuite/c-c++-common/pr37743.c        (revision 207924)
@@ -0,0 +1,13 @@
+/* PR c/37743 */
+/* This needs to be run only on targets where __UINT32_TYPE__ is defined
+   to unsigned int.  */
+/* { dg-do compile { target *-*-linux-gnu* } } */
+/* { dg-options "-Wformat" } */
+
+int foo (const char *, ...) __attribute__ ((format (printf, 1, 2)));
+
+void
+bar (unsigned int x)
+{
+  foo ("%x", __builtin_bswap32 (x));
+}
2014-03-06  Jakub Jelinek  <ja...@redhat.com>

        * Makefile.in (tree-ssa-uninit.o): Depend on $(PARAMS_H).

        Backport from mainline
        2014-02-21  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/56490
        * params.def (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS): New param.
        * tree-ssa-uninit.c: Include params.h.
        (compute_control_dep_chain): Add num_calls argument, return false
        if it exceed PARAM_UNINIT_CONTROL_DEP_ATTEMPTS param, pass
        num_calls to recursive call.
        (find_predicates): Change dep_chain into normal array, add num_calls
        variable and adjust compute_control_dep_chain caller.
        (find_def_preds): Likewise.

--- gcc/params.def      (revision 207987)
+++ gcc/params.def      (revision 207988)
@@ -1014,6 +1014,12 @@ DEFPARAM (PARAM_MAX_SLSR_CANDIDATE_SCAN,
          "strength reduction",
          50, 1, 999999)
 
+DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS,
+         "uninit-control-dep-attempts",
+         "Maximum number of nested calls to search for control dependencies "
+         "during uninitialized variable analysis",
+         1000, 1, 0)
+
 /*
 Local variables:
 mode:c
--- gcc/tree-ssa-uninit.c       (revision 207987)
+++ gcc/tree-ssa-uninit.c       (revision 207988)
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.
 #include "hashtab.h"
 #include "tree-pass.h"
 #include "diagnostic-core.h"
+#include "params.h"
 
 /* This implements the pass that does predicate aware warning on uses of
    possibly uninitialized variables. The pass first collects the set of
@@ -246,8 +247,8 @@ find_control_equiv_block (basic_block bb
 
 /* Computes the control dependence chains (paths of edges)
    for DEP_BB up to the dominating basic block BB (the head node of a
-   chain should be dominated by it).  CD_CHAINS is pointer to a
-   dynamic array holding the result chains. CUR_CD_CHAIN is the current
+   chain should be dominated by it).  CD_CHAINS is pointer to an
+   array holding the result chains.  CUR_CD_CHAIN is the current
    chain being computed.  *NUM_CHAINS is total number of chains.  The
    function returns true if the information is successfully computed,
    return false if there is no control dependence or not computed.  */
@@ -256,7 +257,8 @@ static bool
 compute_control_dep_chain (basic_block bb, basic_block dep_bb,
                            vec<edge> *cd_chains,
                            size_t *num_chains,
-                           vec<edge> *cur_cd_chain)
+                          vec<edge> *cur_cd_chain,
+                          int *num_calls)
 {
   edge_iterator ei;
   edge e;
@@ -267,6 +269,10 @@ compute_control_dep_chain (basic_block b
   if (EDGE_COUNT (bb->succs) < 2)
     return false;
 
+  if (*num_calls > PARAM_VALUE (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS))
+    return false;
+  ++*num_calls;
+
   /* Could  use a set instead.  */
   cur_chain_len = cur_cd_chain->length ();
   if (cur_chain_len > MAX_CHAIN_LEN)
@@ -306,7 +312,7 @@ compute_control_dep_chain (basic_block b
 
           /* Now check if DEP_BB is indirectly control dependent on BB.  */
           if (compute_control_dep_chain (cd_bb, dep_bb, cd_chains,
-                                         num_chains, cur_cd_chain))
+                                        num_chains, cur_cd_chain, num_calls))
             {
               found_cd_chain = true;
               break;
@@ -438,14 +444,12 @@ find_predicates (vec<use_pred_info_t> **
                  basic_block use_bb)
 {
   size_t num_chains = 0, i;
-  vec<edge> *dep_chains = 0;
+  int num_calls = 0;
+  vec<edge> dep_chains[MAX_NUM_CHAINS];
   vec<edge> cur_chain = vNULL;
   bool has_valid_pred = false;
   basic_block cd_root = 0;
 
-  typedef vec<edge> vec_edge_heap;
-  dep_chains = XCNEWVEC (vec_edge_heap, MAX_NUM_CHAINS);
-
   /* First find the closest bb that is control equivalent to PHI_BB
      that also dominates USE_BB.  */
   cd_root = phi_bb;
@@ -458,20 +462,16 @@ find_predicates (vec<use_pred_info_t> **
         break;
     }
 
-  compute_control_dep_chain (cd_root, use_bb,
-                             dep_chains, &num_chains,
-                             &cur_chain);
+  compute_control_dep_chain (cd_root, use_bb, dep_chains, &num_chains,
+                            &cur_chain, &num_calls);
 
   has_valid_pred
-      = convert_control_dep_chain_into_preds (dep_chains,
-                                              num_chains,
-                                              preds,
-                                              num_preds);
+    = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds,
+                                           num_preds);
   /* Free individual chain  */
   cur_chain.release ();
   for (i = 0; i < num_chains; i++)
     dep_chains[i].release ();
-  free (dep_chains);
   return has_valid_pred;
 }
 
@@ -539,16 +539,13 @@ find_def_preds (vec<use_pred_info_t> **p
                 size_t *num_preds, gimple phi)
 {
   size_t num_chains = 0, i, n;
-  vec<edge> *dep_chains = 0;
+  vec<edge> dep_chains[MAX_NUM_CHAINS];
   vec<edge> cur_chain = vNULL;
   vec<edge> def_edges = vNULL;
   bool has_valid_pred = false;
   basic_block phi_bb, cd_root = 0;
   struct pointer_set_t *visited_phis;
 
-  typedef vec<edge> vec_edge_heap;
-  dep_chains = XCNEWVEC (vec_edge_heap, MAX_NUM_CHAINS);
-
   phi_bb = gimple_bb (phi);
   /* First find the closest dominating bb to be
      the control dependence root  */
@@ -567,38 +564,33 @@ find_def_preds (vec<use_pred_info_t> **p
   for (i = 0; i < n; i++)
     {
       size_t prev_nc, j;
+      int num_calls = 0;
       edge opnd_edge;
 
       opnd_edge = def_edges[i];
       prev_nc = num_chains;
-      compute_control_dep_chain (cd_root, opnd_edge->src,
-                                 dep_chains, &num_chains,
-                                 &cur_chain);
-      /* Free individual chain  */
-      cur_chain.release ();
+      compute_control_dep_chain (cd_root, opnd_edge->src, dep_chains,
+                                &num_chains, &cur_chain, &num_calls);
 
       /* Now update the newly added chains with
          the phi operand edge:  */
       if (EDGE_COUNT (opnd_edge->src->succs) > 1)
         {
-          if (prev_nc == num_chains
-              && num_chains < MAX_NUM_CHAINS)
-            num_chains++;
+         if (prev_nc == num_chains && num_chains < MAX_NUM_CHAINS)
+           dep_chains[num_chains++] = vNULL;
           for (j = prev_nc; j < num_chains; j++)
-            {
-              dep_chains[j].safe_push (opnd_edge);
-            }
+           dep_chains[j].safe_push (opnd_edge);
         }
     }
 
+  /* Free individual chain  */
+  cur_chain.release ();
+
   has_valid_pred
-      = convert_control_dep_chain_into_preds (dep_chains,
-                                              num_chains,
-                                              preds,
-                                              num_preds);
+    = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds,
+                                           num_preds);
   for (i = 0; i < num_chains; i++)
     dep_chains[i].release ();
-  free (dep_chains);
   return has_valid_pred;
 }
 
--- gcc/Makefile.in     2013-12-11 14:43:58.000000000 +0100
+++ gcc/Makefile.in     2014-03-05 21:30:28.839269860 +0100
@@ -2256,7 +2256,7 @@ tree-ssa-uninit.o : tree-ssa-uninit.c $(
    $(FUNCTION_H) $(TM_H) coretypes.h \
    $(TREE_PASS_H) $(BASIC_BLOCK_H) $(BITMAP_H) \
    $(FLAGS_H) $(HASHTAB_H) pointer-set.h \
-   $(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
+   $(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H)
 tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) $(TM_P_H) $(EXPR_H) $(DIAGNOSTIC_H) \
    toplev.h $(FUNCTION_H) $(TM_H) coretypes.h \
2014-03-06  Jakub Jelinek  <ja...@redhat.com>

        Backport from mainline
        2014-02-08  Jakub Jelinek  <ja...@redhat.com>

        PR ipa/60026
        * ipa-cp.c (determine_versionability): Fail at -O0
        or __attribute__((optimize (0))) or -fno-ipa-cp functions.
        * tree-sra.c (ipa_sra_preliminary_function_checks): Similarly.

        2014-02-06  Jakub Jelinek  <ja...@redhat.com>

        PR target/60062
        * tree.h (opts_for_fn): New inline function.
        (opt_for_fn): Define.
        * config/i386/i386.c (ix86_function_regparm): Use
        opt_for_fn (decl, optimize) instead of optimize.

        * gcc.c-torture/execute/pr60062.c: New test.
        * gcc.c-torture/execute/pr60072.c: New test.

        2014-02-04  Jakub Jelinek  <ja...@redhat.com>

        PR ipa/60026
        * c-c++-common/torture/pr60026.c: New test.

--- gcc/tree.h  (revision 207548)
+++ gcc/tree.h  (revision 207549)
@@ -6546,4 +6546,18 @@ builtin_decl_implicit_p (enum built_in_f
          && builtin_info.implicit_p[uns_fncode]);
 }
 
+/* Return pointer to optimization flags of FNDECL.  */
+static inline struct cl_optimization *
+opts_for_fn (const_tree fndecl)
+{
+  tree fn_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
+  if (fn_opts == NULL_TREE)
+    fn_opts = optimization_default_node;
+  return TREE_OPTIMIZATION (fn_opts);
+}
+
+/* opt flag for function FNDECL, e.g. opts_for_fn (fndecl, optimize) is
+   the optimization level of function fndecl.  */
+#define opt_for_fn(fndecl, opt) (opts_for_fn (fndecl)->x_##opt)
+
 #endif  /* GCC_TREE_H  */
--- gcc/ipa-cp.c        (revision 207620)
+++ gcc/ipa-cp.c        (revision 207621)
@@ -444,6 +444,9 @@ determine_versionability (struct cgraph_
     reason = "not a tree_versionable_function";
   else if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
     reason = "insufficient body availability";
+  else if (!opt_for_fn (node->symbol.decl, optimize)
+          || !opt_for_fn (node->symbol.decl, flag_ipa_cp))
+    reason = "non-optimized function";
 
   if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
     fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
--- gcc/tree-sra.c      (revision 207620)
+++ gcc/tree-sra.c      (revision 207621)
@@ -4900,6 +4900,14 @@ ipa_sra_preliminary_function_checks (str
       return false;
     }
 
+  if (!opt_for_fn (node->symbol.decl, optimize)
+      || !opt_for_fn (node->symbol.decl, flag_ipa_sra))
+    {
+      if (dump_file)
+       fprintf (dump_file, "Function not optimized.\n");
+      return false;
+    }
+
   if (DECL_VIRTUAL_P (current_function_decl))
     {
       if (dump_file)
--- gcc/config/i386/i386.c      (revision 207548)
+++ gcc/config/i386/i386.c      (revision 207549)
@@ -5608,7 +5608,12 @@ ix86_function_regparm (const_tree type,
   /* Use register calling convention for local functions when possible.  */
   if (decl
       && TREE_CODE (decl) == FUNCTION_DECL
-      && optimize
+      /* Caller and callee must agree on the calling convention, so
+        checking here just optimize means that with
+        __attribute__((optimize (...))) caller could use regparm convention
+        and callee not, or vice versa.  Instead look at whether the callee
+        is optimized or not.  */
+      && opt_for_fn (decl, optimize)
       && !(profile_flag && !flag_fentry))
     {
       /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified.  */
--- gcc/testsuite/gcc.c-torture/execute/pr60062.c       (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr60062.c       (revision 207549)
@@ -0,0 +1,25 @@
+/* PR target/60062 */
+
+int a;
+
+static void
+foo (const char *p1, int p2)
+{
+  if (__builtin_strcmp (p1, "hello") != 0)
+    __builtin_abort ();
+}
+
+static void
+bar (const char *p1)
+{
+  if (__builtin_strcmp (p1, "hello") != 0)
+    __builtin_abort ();
+}
+
+__attribute__((optimize (0))) int
+main ()
+{
+  foo ("hello", a);
+  bar ("hello");
+  return 0;
+}
--- gcc/testsuite/gcc.c-torture/execute/pr60072.c       (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr60072.c       (revision 207549)
@@ -0,0 +1,16 @@
+/* PR target/60072 */
+
+int c = 1;
+
+__attribute__ ((optimize (1)))
+static int *foo (int *p)
+{
+  return p;
+}
+
+int
+main ()
+{
+  *foo (&c) = 2;
+  return c - 2;
+}
--- gcc/testsuite/c-c++-common/torture/pr60026.c        (revision 0)
+++ gcc/testsuite/c-c++-common/torture/pr60026.c        (revision 207463)
@@ -0,0 +1,28 @@
+/* PR ipa/60026 */
+/* { dg-do compile } */
+
+struct S { int f; } a;
+
+__attribute__((optimize (0)))
+struct S foo (int x, struct S y)
+{
+  int b = y.f;
+  return a; 
+}
+
+void
+bar ()
+{
+  while (a.f)
+    {
+      struct S c = {0};
+      foo (0, c);
+    }
+}
+
+int
+main ()
+{
+  bar (); 
+  return 0;
+}

Reply via email to