1  /* PR tree-optimization/20601 */
       2  extern void abort (void);
       3  extern void exit (int);
       4  
       5  struct T
       6  {
       7    char *t1;
       8    char t2[4096];
       9    char **t3;
      10  };
      11  
      12  int a[5];
      13  int b;
      14  char **c;
      15  int d;
      16  char **e;
      17  struct T t;
      18  char *f[16];
      19  char *g[] = { "a", "-u", "b", "c" };
      20  
      21  __attribute__ ((__noreturn__)) void
      22  foo (void)
      23  {
      24    while (1);
      25  }
      26  
      27  __attribute__ ((noinline)) char *
      28  bar (char *x, unsigned int y)
      29  {
      30    return 0;
      31  }
      32  
      33  static inline char *
      34  baz (char *x, unsigned int y)
      35  {
      36    if (sizeof (t.t2) != (unsigned int) -1 && y > sizeof (t.t2))
      37      foo ();
      38    return bar (x, y);
      39  }
      40  
      41  static inline int
      42  setup1 (int x)
      43  {
      44    char *p;
      45    int rval;
      46  
      47    if (!baz (t.t2, sizeof (t.t2)))
      48      baz (t.t2, sizeof (t.t2));
      49  
      50    if (x & 0x200)
      51      {
      52        char **h, **i = e;
      53  
      54        ++d;
      55        e = f;
      56        if (t.t1 && *t.t1)
      57          e[0] = t.t1;
      58        else
      59          abort ();
      60  
      61        for (h = e + 1; (*h = *i); ++i, ++h)
      62          ;
      63      }
      64    return 1;
      65  }
      66  
      67  static inline int
      68  setup2 (void)
      69  {
      70    int j = 1;
      71  
      72    e = c + 1;
      73    d = b - 1;
      74    while (d > 0 && e[0][0] == '-')
      75      {
      76        if (e[0][1] != '\0' && e[0][2] != '\0')
      77          abort ();
      78  
      79        switch (e[0][1])
      80          {
      81          case 'u':
      82            if (!e[1])
      83              abort ();
      84  
      85            t.t3 = &e[1];
      86            d--;
      87            e++;
      88            break;
      89          case 'P':
      90            j |= 0x1000;
      91            break;
      92          case '-':
      93            d--;
      94            e++;
      95            if (j == 1)
      96              j |= 0x600;
      97            return j;
      98          }
      99        d--;
     100        e++;
     101      }
     102  
     103    if (d > 0 && !(j & 1))
     104      abort ();
     105  
     106    return j;
     107  }
     108  
     109  int
     110  main (void)
     111  {
     112    int x;
     113    c = g;
     114    b = 4;
     115    x = setup2 ();
     116    t.t1 = "/bin/sh";
     117    setup1 (x);
     118    /* PRE shouldn't transform x into the constant 0x601 here, it's not legal.  */
     119    if ((x & 0x400) && !a[4])
     120      abort ();
     121    exit (0);
     122  }