Hi!

I've committed these backports to 4.5 branch after bootstrapping/regtesting
them on x86_64-linux and i686-linux.

        Jakub
2012-02-09  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2012-01-26  Jakub Jelinek  <ja...@redhat.com>

        * make-relative-prefix.c (make_relative_prefix_1): Avoid warning
        about using preprocessor directives inside of macro arguments.

        2012-01-02  Jakub Jelinek  <ja...@redhat.com>

        * make-relative-prefix.c (make_relative_prefix_1): Avoid
        stack overflow if PATH contains just a single entry and
        HOST_EXECUTABLE_SUFFIX needs to be used.

        PR driver/48306
        * make-relative-prefix.c: Include sys/stat.h.
        (make_relative_prefix_1): If access succeeds, check also stat
        if nstore is a regular file.

--- libiberty/make-relative-prefix.c    (revision 182819)
+++ libiberty/make-relative-prefix.c    (revision 183561)
@@ -58,6 +58,9 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
 
 #include <string.h>
 
@@ -245,10 +248,15 @@
        {
          char *startp, *endp, *nstore;
          size_t prefixlen = strlen (temp) + 1;
+         size_t len;
          if (prefixlen < 2)
            prefixlen = 2;
 
-         nstore = (char *) alloca (prefixlen + strlen (progname) + 1);
+         len = prefixlen + strlen (progname) + 1;
+#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
+         len += strlen (HOST_EXECUTABLE_SUFFIX);
+#endif
+         nstore = (char *) alloca (len);
 
          startp = endp = temp;
          while (1)
@@ -263,7 +271,7 @@
                    }
                  else
                    {
-                     strncpy (nstore, startp, endp - startp);
+                     memcpy (nstore, startp, endp - startp);
                      if (! IS_DIR_SEPARATOR (endp[-1]))
                        {
                          nstore[endp - startp] = DIR_SEPARATOR;
@@ -279,8 +287,14 @@
 #endif
                      )
                    {
-                     progname = nstore;
-                     break;
+#if defined (HAVE_SYS_STAT_H) && defined (S_ISREG)
+                     struct stat st;
+                     if (stat (nstore, &st) >= 0 && S_ISREG (st.st_mode))
+#endif
+                       {
+                         progname = nstore;
+                         break;
+                       }
                    }
 
                  if (*endp == 0)
2012-02-09  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2012-01-05  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/51768
        * stmt.c (check_unique_operand_names): Don't ICE during error
        reporting if i is from labels chain.

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

--- gcc/stmt.c  (revision 182920)
+++ gcc/stmt.c  (revision 182921)
@@ -1253,11 +1253,11 @@ check_operand_nalternatives (tree output
 static bool
 check_unique_operand_names (tree outputs, tree inputs, tree labels)
 {
-  tree i, j;
+  tree i, j, i_name = NULL_TREE;
 
   for (i = outputs; i ; i = TREE_CHAIN (i))
     {
-      tree i_name = TREE_PURPOSE (TREE_PURPOSE (i));
+      i_name = TREE_PURPOSE (TREE_PURPOSE (i));
       if (! i_name)
        continue;
 
@@ -1268,7 +1268,7 @@ check_unique_operand_names (tree outputs
 
   for (i = inputs; i ; i = TREE_CHAIN (i))
     {
-      tree i_name = TREE_PURPOSE (TREE_PURPOSE (i));
+      i_name = TREE_PURPOSE (TREE_PURPOSE (i));
       if (! i_name)
        continue;
 
@@ -1282,7 +1282,7 @@ check_unique_operand_names (tree outputs
 
   for (i = labels; i ; i = TREE_CHAIN (i))
     {
-      tree i_name = TREE_PURPOSE (i);
+      i_name = TREE_PURPOSE (i);
       if (! i_name)
        continue;
 
@@ -1297,8 +1297,7 @@ check_unique_operand_names (tree outputs
   return true;
 
  failure:
-  error ("duplicate asm operand name %qs",
-        TREE_STRING_POINTER (TREE_PURPOSE (TREE_PURPOSE (i))));
+  error ("duplicate asm operand name %qs", TREE_STRING_POINTER (i_name));
   return false;
 }
 
--- gcc/testsuite/c-c++-common/pr51768.c        (revision 0)
+++ gcc/testsuite/c-c++-common/pr51768.c        (revision 182921)
@@ -0,0 +1,25 @@
+/* PR middle-end/51768 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (void)
+{
+  asm goto ("" : : : : lab, lab, lab2, lab);   /* { dg-error "duplicate asm 
operand name" } */
+lab:;
+lab2:;
+}
+
+void
+bar (void)
+{
+  asm goto ("" : : [lab] "i" (0) : : lab);     /* { dg-error "duplicate asm 
operand name" } */
+lab:;
+}
+
+void
+baz (void)
+{
+  int x;
+  asm ("" : [lab] "=r" (x) : [lab] "r" (x));   /* { dg-error "duplicate asm 
operand name" } */
+}
2012-02-09  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2012-01-05  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/51767
        * cfgrtl.c (force_nonfallthru_and_redirect): Force addition
        of jump_block and add an extra edge for degenerated asm gotos.

        * gcc.c-torture/compile/pr51767.c: New test.

--- gcc/cfgrtl.c        (revision 182921)
+++ gcc/cfgrtl.c        (revision 182922)
@@ -1129,6 +1129,7 @@ force_nonfallthru_and_redirect (edge e, 
   rtx note;
   edge new_edge;
   int abnormal_edge_flags = 0;
+  bool asm_goto_edge = false;
   int loc;
 
   /* In the case the last instruction is conditional jump to the next
@@ -1208,8 +1209,28 @@ force_nonfallthru_and_redirect (edge e, 
        }
     }
 
-  if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags)
+  /* If e->src ends with asm goto, see if any of the ASM_OPERANDS_LABELs
+     don't point to target label.  */
+  if (JUMP_P (BB_END (e->src))
+      && target != EXIT_BLOCK_PTR
+      && e->dest == target
+      && (e->flags & EDGE_FALLTHRU)
+      && (note = extract_asm_operands (PATTERN (BB_END (e->src)))))
     {
+      int i, n = ASM_OPERANDS_LABEL_LENGTH (note);
+
+      for (i = 0; i < n; ++i)
+       if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target))
+         {
+           asm_goto_edge = true;
+           break;
+         }
+    }
+
+  if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge)
+    {
+      gcov_type count = e->count;
+      int probability = e->probability;
       /* Create the new structures.  */
 
       /* If the old block ended with a tablejump, skip its table
@@ -1220,7 +1241,7 @@ force_nonfallthru_and_redirect (edge e, 
       note = NEXT_INSN (note);
 
       jump_block = create_basic_block (note, NULL, e->src);
-      jump_block->count = e->count;
+      jump_block->count = count;
       jump_block->frequency = EDGE_FREQUENCY (e);
       jump_block->loop_depth = target->loop_depth;
 
@@ -1236,13 +1257,27 @@ force_nonfallthru_and_redirect (edge e, 
 
       /* Wire edge in.  */
       new_edge = make_edge (e->src, jump_block, EDGE_FALLTHRU);
-      new_edge->probability = e->probability;
-      new_edge->count = e->count;
+      new_edge->probability = probability;
+      new_edge->count = count;
 
       /* Redirect old edge.  */
       redirect_edge_pred (e, jump_block);
       e->probability = REG_BR_PROB_BASE;
 
+      /* If asm goto has any label refs to target's label,
+        add also edge from asm goto bb to target.  */
+      if (asm_goto_edge)
+       {
+         new_edge->probability /= 2;
+         new_edge->count /= 2;
+         jump_block->count /= 2;
+         jump_block->frequency /= 2;
+         new_edge = make_edge (new_edge->src, target,
+                               e->flags & ~EDGE_FALLTHRU);
+         new_edge->probability = probability - probability / 2;
+         new_edge->count = count - count / 2;
+       }
+
       new_bb = jump_block;
     }
   else
--- gcc/testsuite/gcc.c-torture/compile/pr51767.c       (revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr51767.c       (revision 182922)
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/51767 */
+
+extern void fn1 (void), fn2 (void);
+
+static inline __attribute__((always_inline)) int
+foo (int *x, long y)
+{
+  asm goto ("" : : "r" (x), "r" (y) : "memory" : lab);
+  return 0;
+lab:
+  return 1;
+}
+
+void
+bar (int *x)
+{
+  if (foo (x, 23))
+    fn1 ();
+  else
+    fn2 ();
+
+  foo (x, 2);
+}
2012-02-09  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2012-01-19  Jakub Jelinek  <ja...@redhat.com>

        PR libmudflap/40778
        * tree-mudflap.c (mf_artificial): New function.
        (execute_mudflap_function_ops, execute_mudflap_function_decls,
        mx_register_decls, mudflap_enqueue_decl): Use it.

        * testsuite/libmudflap.c/fail68-frag.c: New test.

--- gcc/tree-mudflap.c  (revision 183306)
+++ gcc/tree-mudflap.c  (revision 183307)
@@ -69,6 +69,13 @@ static tree mx_xfn_xform_decls (gimple_s
 static gimple_seq mx_register_decls (tree, gimple_seq, location_t);
 static unsigned int execute_mudflap_function_decls (void);
 
+/* Return true if DECL is artificial stub that shouldn't be instrumented by
+   mf.  We should instrument clones of non-artificial functions.  */
+static inline bool
+mf_artificial (const_tree decl)
+{
+  return DECL_ARTIFICIAL (DECL_ORIGIN (decl));
+}
 
 /* ------------------------------------------------------------------------ */
 /* Some generally helpful functions for mudflap instrumentation.  */
@@ -412,8 +419,8 @@ execute_mudflap_function_ops (void)
 
   /* Don't instrument functions such as the synthetic constructor
      built during mudflap_finish_file.  */
-  if (mf_marked_p (current_function_decl) ||
-      DECL_ARTIFICIAL (current_function_decl))
+  if (mf_marked_p (current_function_decl)
+      || mf_artificial (current_function_decl))
     return 0;
 
   push_gimplify_context (&gctx);
@@ -994,8 +1001,8 @@ execute_mudflap_function_decls (void)
 
   /* Don't instrument functions such as the synthetic constructor
      built during mudflap_finish_file.  */
-  if (mf_marked_p (current_function_decl) ||
-      DECL_ARTIFICIAL (current_function_decl))
+  if (mf_marked_p (current_function_decl)
+      || mf_artificial (current_function_decl))
     return 0;
 
   push_gimplify_context (&gctx);
@@ -1078,7 +1085,7 @@ mx_register_decls (tree decl, gimple_seq
           /* Add the __mf_register call at the current appending point.  */
           if (gsi_end_p (initially_stmts))
            {
-             if (!DECL_ARTIFICIAL (decl))
+             if (!mf_artificial (decl))
                warning (OPT_Wmudflap,
                         "mudflap cannot track %qE in stub function",
                         DECL_NAME (decl));
@@ -1249,7 +1256,7 @@ mudflap_enqueue_decl (tree obj)
      during mudflap_finish_file ().  That would confuse the user,
      since the text would refer to variables that don't show up in the
      user's source code.  */
-  if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj))
+  if (DECL_P (obj) && DECL_EXTERNAL (obj) && mf_artificial (obj))
     return;
 
   VEC_safe_push (tree, gc, deferred_static_decls, obj);
--- libmudflap/testsuite/libmudflap.c/fail68-frag.c     (revision 0)
+++ libmudflap/testsuite/libmudflap.c/fail68-frag.c     (revision 183307)
@@ -0,0 +1,27 @@
+/* PR libmudflap/40778 */
+
+char p[32];
+static int j;
+
+__attribute__((noinline))
+static void foo (int i)
+{
+  if (j++ == 0)
+    p[i + 4] = 12;
+  else
+    p[i - 4] = 13;
+}
+
+int
+main ()
+{
+  foo (30);
+  foo (30);
+  foo (30);
+  return 0;
+}
+
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*name.*p" } */
+/* { dg-do run { xfail *-*-* } } */
2012-02-09  Jakub Jelinek  <ja...@redhat.com>

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

        PR rtl-optimization/52139
        * cfgrtl.c (cfg_layout_merge_blocks): If BB_END
        is a BARRIER after emit_insn_after_noloc, move BB_END
        to the last non-BARRIER insn before it.

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

--- gcc/cfgrtl.c        (revision 184004)
+++ gcc/cfgrtl.c        (revision 184005)
@@ -2871,6 +2871,11 @@ cfg_layout_merge_blocks (basic_block a, 
       rtx first = BB_END (a), last;
 
       last = emit_insn_after_noloc (b->il.rtl->header, BB_END (a), a);
+      /* The above might add a BARRIER as BB_END, but as barriers
+        aren't valid parts of a bb, remove_insn doesn't update
+        BB_END if it is a barrier.  So adjust BB_END here.  */
+      while (BB_END (a) != first && BARRIER_P (BB_END (a)))
+       BB_END (a) = PREV_INSN (BB_END (a));
       delete_insn_chain (NEXT_INSN (first), last, false);
       b->il.rtl->header = NULL;
     }
--- gcc/testsuite/gcc.dg/pr52139.c      (revision 0)
+++ gcc/testsuite/gcc.dg/pr52139.c      (revision 184005)
@@ -0,0 +1,49 @@
+/* PR rtl-optimization/52139 */
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-dominator-opts -fno-tree-fre" } */
+/* { dg-options "-O -fno-tree-dominator-opts -fno-tree-fre -fpic" { target 
fpic } } */
+
+void *p;
+
+void
+foo (int a)
+{
+  switch (a)
+    {
+    case 0:
+    a0:
+    case 1:
+    a1:
+      p = &&a1;
+    case 2:
+    a2:
+      p = &&a2;
+    case 3:
+    a3:
+      p = &&a3;
+    case 4:
+    a4:
+      p = &&a4;
+    case 5:
+    a5:
+      p = &&a5;
+    case 6:
+    a6:
+      p = &&a6;
+    case 7:
+    a7:
+      p = &&a7;
+    case 8:
+    a8:
+      p = &&a8;
+    case 9:
+    a9:
+      p = &&a9;
+    case 10:
+    a10:
+      p = &&a10;
+    default:
+      p = &&a0;
+    }
+  goto *p;
+}
2012-02-09  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2012-01-05  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/44777
        * profile.c (branch_prob): Split bbs that have exit edge
        and need a fake entry edge too.

        * gcc.dg/tree-prof/pr44777.c: New test.

--- gcc/profile.c       (revision 182919)
+++ gcc/profile.c       (revision 182920)
@@ -989,6 +989,45 @@ branch_prob (void)
            fprintf (dump_file, "Adding fake entry edge to bb %i\n",
                     bb->index);
          make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
+         /* Avoid bbs that have both fake entry edge and also some
+            exit edge.  One of those edges wouldn't be added to the
+            spanning tree, but we can't instrument any of them.  */
+         if (have_exit_edge || need_exit_edge)
+           {
+             gimple_stmt_iterator gsi;
+             gimple first;
+             tree fndecl;
+
+             gsi = gsi_after_labels (bb);
+#ifdef ENABLE_CHECKING
+             gcc_assert (!gsi_end_p (gsi));
+#endif
+             first = gsi_stmt (gsi);
+             if (is_gimple_debug (first))
+               {
+                 gsi_next_nondebug (&gsi);
+#ifdef ENABLE_CHECKING
+                 gcc_assert (!gsi_end_p (gsi));
+#endif
+                 first = gsi_stmt (gsi);
+               }
+             /* Don't split the bbs containing __builtin_setjmp_receiver
+                or __builtin_setjmp_dispatcher calls.  These are very
+                special and don't expect anything to be inserted before
+                them.  */
+             if (!is_gimple_call (first)
+                 || (fndecl = gimple_call_fndecl (first)) == NULL
+                 || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL
+                 || (DECL_FUNCTION_CODE (fndecl) != BUILT_IN_SETJMP_RECEIVER
+                     && (DECL_FUNCTION_CODE (fndecl)
+                         != BUILT_IN_SETJMP_DISPATCHER)))
+               {
+                 if (dump_file)
+                   fprintf (dump_file, "Splitting bb %i after labels\n",
+                            bb->index);
+                 split_block_after_labels (bb);
+               }
+           }
        }
     }
 
--- gcc/testsuite/gcc.dg/tree-prof/pr44777.c    (revision 0)
+++ gcc/testsuite/gcc.dg/tree-prof/pr44777.c    (revision 182920)
@@ -0,0 +1,43 @@
+/* PR middle-end/44777 */
+/* { dg-options "-O0" } */
+/* A variant of gcc.c-torture/execute/comp-goto-2.c.  */
+
+extern void abort (void);
+extern void exit (int);
+
+#ifdef STACK_SIZE
+#define DEPTH ((STACK_SIZE) / 512 + 1)
+#else
+#define DEPTH 1000
+#endif
+
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+int
+x (int a)
+{
+  __label__ xlab;
+  void y (int a)
+    {
+      void *x = &&llab;
+      if (a==-1)
+       goto *x;
+      if (a==0)
+       goto xlab;
+    llab:
+      y (a-1);
+    }
+  y (a);
+ xlab:;
+  return a;
+}
+#endif
+
+int
+main ()
+{
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+  if (x (DEPTH) != DEPTH)
+    abort ();
+#endif
+  exit (0);
+}

Reply via email to