1  /* PR 64878 */
       2  /* { dg-options "-O2" } */
       3  /* { dg-do run } */
       4  
       5  struct A { int a1; };
       6  struct B { char *b1; int b2; int b3; };
       7  struct C { char *c1; int c2; struct B *c3; };
       8  extern struct A *f1 (char *s);
       9  static struct A *f2 (struct C *x);
      10  __attribute__ ((noinline, noclone)) int f3 (struct A *x, struct A *z) { asm volatile ("" : : "g" (x), "g" (z) : "memory"); return 0; }
      11  __attribute__ ((noinline, noclone)) void f4 (struct A *x, char *y, struct A *z) { asm volatile ("" : : "g" (x), "g" (z), "g" (y) : "memory"); }
      12  __attribute__ ((noinline, noclone)) struct B *f5 (void) { static char b[32]; static struct B f3 = { b, 0, 32 }; return &f3; }
      13  __attribute__ ((noinline, noclone)) int f6 (struct B *p, char *w, int z) { asm volatile ("" : : "g" (p), "g" (w), "g" (z) : "memory"); return 0; }
      14  __attribute__ ((noinline, noclone)) void f7 (struct B *p) { asm volatile ("" : : "g" (p) : "memory"); }
      15  __attribute__ ((noinline, noclone)) void f8 (struct B *p) { asm volatile ("" : : "g" (p) : "memory"); }
      16  __attribute__ ((noinline, noclone)) void f9 (struct A *x) { asm volatile ("" : : "g" (x) : "memory"); }
      17  __attribute__ ((noinline, noclone)) struct A *f10 (void) { static struct A j; asm volatile ("" : :  : "memory"); return &j; }
      18  __attribute__ ((noinline, noclone)) struct A *f11 (void) { static struct A j; asm volatile ("" : :  : "memory"); return &j; }
      19  __attribute__ ((noinline, noclone)) struct A *f12 (int b) { static struct A j; asm volatile ("" : : "g" (b) : "memory"); return &j; }
      20  __attribute__ ((noinline, noclone)) struct A *f13 (int i) { static struct A j; asm volatile ("" : : "g" (i) : "memory"); return &j; }
      21  __attribute__ ((noinline, noclone)) struct A *f14 (double d) { static struct A j; asm volatile ("" : : "g" (&d) : "memory"); return &j; }
      22  __attribute__ ((noinline, noclone)) struct A *f15 (char *s) { static struct A j; asm volatile ("" : : "g" (s) : "memory"); return &j; }
      23  char *t = "0123456789abcdef";
      24  char *u = "0123456789.+-e";
      25  
      26  __attribute__ ((noinline, noclone)) struct A *
      27  f1 (char *s)
      28  {
      29    struct C f;
      30    struct A *o;
      31    f.c1 = s;
      32    f.c2 = 0;
      33    f.c3 = f5 ();
      34    o = f2 (&f);
      35    f8 (f.c3);
      36    return o;
      37  }
      38  
      39  static struct A *
      40  f2 (struct C *x)
      41  {
      42    int a, b, e = 0;
      43    struct A *f = 0, *o;
      44    char *g = 0;
      45    char h = '\0';
      46    int i = 0, j = 0;
      47    a = 0;
      48    b = 1;
      49    char c;
      50    do
      51      {
      52        c = x->c1[x->c2];
      53        switch (a)
      54  	{
      55  	case 0:
      56  	  if (c == ' ')
      57  	    x->c2++;
      58  	  else if (c == '/')
      59  	    {
      60  	      a = 4;
      61  	      j = x->c2++;
      62  	    }
      63  	  else
      64  	    a = b;
      65  	  break;
      66  	case 1:
      67  	  switch (c)
      68  	    {
      69  	    case '{':
      70  	      a = 0;
      71  	      b = 15;
      72  	      f = f10 ();
      73  	      x->c2++;
      74  	      break;
      75  	    case '[':
      76  	      a = 0;
      77  	      b = 13;
      78  	      f = f11 ();
      79  	      x->c2++;
      80  	      break;
      81  	    case 'N':
      82  	    case 'n':
      83  	      a = 3;
      84  	      j = x->c2++;
      85  	      break;
      86  	    case '"':
      87  	    case '\'':
      88  	      h = c;
      89  	      f7 (x->c3);
      90  	      a = 8;
      91  	      j = ++x->c2;
      92  	      break;
      93  	    case 'T':
      94  	    case 't':
      95  	    case 'F':
      96  	    case 'f':
      97  	      a = 11;
      98  	      j = x->c2++;
      99  	      break;
     100  	    case '0' ... '9':
     101  	    case '-':
     102  	      i = 0;
     103  	      a = 12;
     104  	      j = x->c2++;
     105  	      break;
     106  	    default:
     107  	      e = 1;
     108  	      goto out;
     109  	    }
     110  	  break;
     111  	case 2:
     112  	  goto out;
     113  	case 3:
     114  	  if (__builtin_strncmp ("null", x->c1 + j, x->c2 - j))
     115  	    {
     116  	      e = 2;
     117  	      goto out;
     118  	    }
     119  	  if (x->c2 - j == 4)
     120  	    {
     121  	      f = 0;
     122  	      b = 2;
     123  	      a = 0;
     124  	    }
     125  	  else
     126  	    x->c2++;
     127  	  break;
     128  	case 4:
     129  	  if (c == '*')
     130  	    a = 5;
     131  	  else if (c == '/')
     132  	    a = 6;
     133  	  else
     134  	    {
     135  	      e = 8;
     136  	      goto out;
     137  	    }
     138  	  x->c2++;
     139  	  break;
     140  	case 5:
     141  	  if (c == '*')
     142  	    a = 7;
     143  	  x->c2++;
     144  	  break;
     145  	case 6:
     146  	  if (c == '\n')
     147  	    a = 0;
     148  	  x->c2++;
     149  	  break;
     150  	case 7:
     151  	  if (c == '/')
     152  	    a = 0;
     153  	  else
     154  	    a = 5;
     155  	  x->c2++;
     156  	  break;
     157  	case 8:
     158  	  if (c == h)
     159  	    {
     160  	      f6 (x->c3, x->c1 + j, x->c2 - j);
     161  	      f = f15 (x->c3->b1);
     162  	      b = 2;
     163  	      a = 0;
     164  	    }
     165  	  else if (c == '\\')
     166  	    {
     167  	      b = 8;
     168  	      a = 9;
     169  	    }
     170  	  x->c2++;
     171  	  break;
     172  	case 9:
     173  	  switch (c)
     174  	    {
     175  	    case '"':
     176  	    case '\\':
     177  	      f6 (x->c3, x->c1 + j, x->c2 - j - 1);
     178  	      j = x->c2++;
     179  	      a = b;
     180  	      break;
     181  	    case 'b':
     182  	    case 'n':
     183  	    case 'r':
     184  	    case 't':
     185  	      f6 (x->c3, x->c1 + j, x->c2 - j - 1);
     186  	      if (c == 'b')
     187  		f6 (x->c3, "\b", 1);
     188  	      else if (c == 'n')
     189  		f6 (x->c3, "\n", 1);
     190  	      else if (c == 'r')
     191  		f6 (x->c3, "\r", 1);
     192  	      else if (c == 't')
     193  		f6 (x->c3, "\t", 1);
     194  	      j = ++x->c2;
     195  	      a = b;
     196  	      break;
     197  	    case 'u':
     198  	      f6 (x->c3, x->c1 + j, x->c2 - j - 1);
     199  	      j = ++x->c2;
     200  	      a = 10;
     201  	      break;
     202  	    default:
     203  	      e = 7;
     204  	      goto out;
     205  	    }
     206  	  break;
     207  	case 10:
     208  	  if (__builtin_strchr (t, c))
     209  	    {
     210  	      x->c2++;
     211  	      if (x->c2 - j == 4)
     212  		{
     213  		  unsigned char w[3];
     214  		  unsigned int s =
     215  		    (((x->c1[j] <= '9') ? x->c1[j] - '0' : (x->c1[j] & 7) + 9) << 12)
     216  		    + (((x->c1[j + 1] <= '9') ? x->c1[j + 1] - '0' : (x->c1[j + 1] & 7) + 9) << 8)
     217  		    + (((x->c1[j + 2] <= '9') ? x->c1[j + 2] - '0' : (x->c1[j + 2] & 7) + 9) << 4)
     218  		    + ((x->c1[j + 3] <= '9') ? x->c1[j + 3] - '0' : (x->c1[j + 3] & 7) + 9);
     219  		  if (s < 0x80)
     220  		    {
     221  		      w[0] = s;
     222  		      f6 (x->c3, (char *) w, 1);
     223  		    }
     224  		  else if (s < 0x800)
     225  		    {
     226  		      w[0] = 0xc0 | (s >> 6);
     227  		      w[1] = 0x80 | (s & 0x3f);
     228  		      f6 (x->c3, (char *) w, 2);
     229  		    }
     230  		  else
     231  		    {
     232  		      w[0] = 0x0 | (s >> 12);
     233  		      w[1] = 0x80 | ((s >> 6) & 0x3f);
     234  		      w[2] = 0x80 | (s & 0x3f);
     235  		      f6 (x->c3, (char *) w, 3);
     236  		    }
     237  		  j = x->c2;
     238  		  a = b;
     239  		}
     240  	    }
     241  	  else
     242  	    {
     243  	      e = 7;
     244  	      goto out;
     245  	    }
     246  	  break;
     247  	case 11:
     248  	  if (__builtin_strncmp ("true", x->c1 + j, x->c2 - j) == 0)
     249  	    {
     250  	      if (x->c2 - j == 4)
     251  		{
     252  		  f = f12 (1);
     253  		  b = 2;
     254  		  a = 0;
     255  		}
     256  	      else
     257  		x->c2++;
     258  	    }
     259  	  else if (__builtin_strncmp ("false", x->c1 + j, x->c2 - j) == 0)
     260  	    {
     261  	      if (x->c2 - j == 5)
     262  		{
     263  		  f = f12 (0);
     264  		  b = 2;
     265  		  a = 0;
     266  		}
     267  	      else
     268  		x->c2++;
     269  	    }
     270  	  else
     271  	    {
     272  	      e = 3;
     273  	      goto out;
     274  	    }
     275  	  break;
     276  	case 12:
     277  	  if (!c || !__builtin_strchr (u, c))
     278  	    {
     279  	      if (!i)
     280  		f = f13 (0);
     281  	      else
     282  		f = f14 (0.0);
     283  	      b = 2;
     284  	      a = 0;
     285  	    }
     286  	  else
     287  	    {
     288  	      if (c == '.' || c == 'e')
     289  		i = 1;
     290  	      x->c2++;
     291  	    }
     292  	  break;
     293  	case 13:
     294  	  if (c == ']')
     295  	    {
     296  	      x->c2++;
     297  	      b = 2;
     298  	      a = 0;
     299  	    }
     300  	  else
     301  	    {
     302  	      o = f2 (x);
     303  #if __SIZEOF_POINTER__ == __SIZEOF_LONG__ && !__MSP430X_LARGE__
     304  	      if (((unsigned long) o > (unsigned long) -4000L))
     305  #else
     306  	  if (((__UINTPTR_TYPE__) o > (__UINTPTR_TYPE__) -4000UL))
     307  #endif
     308  		{
     309  		  e = 5;
     310  		  goto out;
     311  		}
     312  	      f3 (f, o);
     313  	      b = 14;
     314  	      a = 0;
     315  	    }
     316  	  break;
     317  	case 14:
     318  	  if (c == ']')
     319  	    {
     320  	      x->c2++;
     321  	      b = 2;
     322  	      a = 0;
     323  	    }
     324  	  else if (c == ',')
     325  	    {
     326  	      x->c2++;
     327  	      b = 13;
     328  	      a = 0;
     329  	    }
     330  	  else
     331  	    {
     332  	      f9 (f);
     333  	      e = 5;
     334  	      goto out;
     335  	    }
     336  	  break;
     337  	case 15:
     338  	  a = 16;
     339  	  j = x->c2;
     340  	  break;
     341  	case 16:
     342  	  if (c == '}')
     343  	    {
     344  	      x->c2++;
     345  	      b = 2;
     346  	      a = 0;
     347  	    }
     348  	  else if (c == '"' || c == '\'')
     349  	    {
     350  	      h = c;
     351  	      f7 (x->c3);
     352  	      a = 17;
     353  	      j = ++x->c2;
     354  	    }
     355  	  else
     356  	    {
     357  	      e = 6;
     358  	      goto out;
     359  	    }
     360  	  break;
     361  	case 17:
     362  	  if (c == h)
     363  	    {
     364  	      f6 (x->c3, x->c1 + j, x->c2 - j);
     365  	      g = __builtin_strdup (x->c3->b1);
     366  	      b = 18;
     367  	      a = 0;
     368  	    }
     369  	  else if (c == '\\')
     370  	    {
     371  	      b = 17;
     372  	      a = 9;
     373  	    }
     374  	  x->c2++;
     375  	  break;
     376  	case 18:
     377  	  if (c == ':')
     378  	    {
     379  	      x->c2++;
     380  	      b = 19;
     381  	      a = 0;
     382  	    }
     383  	  else
     384  	    {
     385  	      e = -6;
     386  	      goto out;
     387  	    }
     388  	  break;
     389  	case 19:
     390  	  o = f2 (x);
     391  #if __SIZEOF_POINTER__ == __SIZEOF_LONG__ && !__MSP430X_LARGE__
     392  	  if (((unsigned long) o > (unsigned long) -4000L))
     393  #else
     394  	  if (((__UINTPTR_TYPE__) o > (__UINTPTR_TYPE__) -4000UL))
     395  #endif
     396  	    {
     397  	      e = 6;
     398  	      goto out;
     399  	    }
     400  	  f4 (f, g, o);
     401  	  __builtin_free (g);
     402  	  g = 0;
     403  	  b = 20;
     404  	  a = 0;
     405  	  break;
     406  	case 20:
     407  	  if (c == '}')
     408  	    {
     409  	      x->c2++;
     410  	      b = 2;
     411  	      a = 0;
     412  	    }
     413  	  else if (c == ',')
     414  	    {
     415  	      x->c2++;
     416  	      b = 15;
     417  	      a = 0;
     418  	    }
     419  	  else
     420  	    {
     421  	      e = 6;
     422  	      goto out;
     423  	    }
     424  	  break;
     425  	}
     426      }
     427    while (c);
     428    if (a != 2 && b != 2)
     429      e = 9;
     430  out:
     431    __builtin_free (g);
     432    if (e == 0)
     433      return f;
     434    f9 (f);
     435    return 0;
     436  }
     437  
     438  int
     439  main ()
     440  {
     441    asm volatile ("" : : : "memory");
     442    struct A *r = f1 ("{ \"id\": null, \"blahah\": \"foobarbazbar\", \"barbar\": { \"barbarbarba\":"
     443  		    "\"abcdefgh\", \"ijklmnopqr\": \"stuvwxyzabcdefghijklmnopqrstuv\", \"xyzxyz\":"
     444  		    " [ \"1\" ] } }");
     445    if (!r)
     446      __builtin_abort ();
     447    return 0;
     448  }