Hi!

As mentioned in the PR, ggc_collect is ok with GTY char * fields to point
outside of GC memory, or if it points at the start of a GC chunk, or
to the start of the STRING_CST string, anything else is not allowed.

parse_optimize_options constructs the whole option like "-falign-jumps=16"
into GC memory and then the option code puts into the arg pointer to
that 16 within that string and if we get ggc_collect after that, we
get ICE.

Fixed by using opts_obstack instead.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-11-14  Jakub Jelinek  <ja...@redhat.com>

        PR other/88007
        * c-common.c (parse_optimize_options): Allocate option string from
        opts_obstack rather than as GC memory.  Move the allocation after
        warning for invalid option.

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

--- gcc/c-family/c-common.c.jj  2018-11-14 00:55:39.359532382 +0100
+++ gcc/c-family/c-common.c     2018-11-14 10:22:13.673689852 +0100
@@ -5523,8 +5523,6 @@ parse_optimize_options (tree args, bool
                  next_p = NULL;
                }
 
-             r = q = (char *) ggc_alloc_atomic (len2 + 3);
-
              /* If the user supplied -Oxxx or -fxxx, only allow -Oxxx or -fxxx
                 options.  */
              if (*p == '-' && p[1] != 'O' && p[1] != 'f')
@@ -5539,6 +5537,9 @@ parse_optimize_options (tree args, bool
                  continue;
                }
 
+             /* Can't use GC memory here, see PR88007.  */
+             r = q = XOBNEWVEC (&opts_obstack, char, len2 + 3);
+
              if (*p != '-')
                {
                  *r++ = '-';
--- gcc/testsuite/gcc.dg/pr88007.c.jj   2018-11-14 10:06:51.493890122 +0100
+++ gcc/testsuite/gcc.dg/pr88007.c      2018-11-14 10:07:26.749309009 +0100
@@ -0,0 +1,15 @@
+/* PR other/88007 */
+/* { dg-do compile } */
+/* { dg-options "--param ggc-min-expand=3 --param ggc-min-heapsize=1024" } */
+/* { dg-skip-if "no code alignment > 2" { "pdp11-*-*" } } */
+
+void bar (void);
+
+__attribute__((optimize ("align-loops=16", "align-jumps=16",
+                        "align-labels=16", "align-functions=16")))
+void
+foo (void)
+{
+  for (int i = 0; i < 1024; ++i)
+    bar ();
+}

        Jakub

Reply via email to