1  /* PR tree-optimization/83431 - Verify that snprintf (0, 0, "%s",
       2     with an argument that's a conditional expression evaluates to
       3     the expected result regardless of the order of the expression
       4     operands.
       5     { dg-do run }
       6     { dg-skip-if "UNIX 2003 return behavior not supported" { hppa*-*-hpux* } }
       7     { dg-options "-O2 -Wall" } */
       8  
       9  #include "strlenopt.h"
      10  
      11  #define A(expr)                                                 \
      12    ((expr)                                                       \
      13     ? (void)0                                                    \
      14     : (__builtin_printf ("assertion failed on line %i: %s\n",    \
      15                          __LINE__, #expr),                       \
      16        __builtin_abort ()))
      17  
      18  const char gs0[] = "";
      19  const char gs3[] = "123";
      20  
      21  char gc;
      22  char ga5[7];
      23  
      24  struct S { char n, ma7[7], max[]; };
      25  
      26  
      27  __attribute__ ((noclone, noinline, noipa)) void
      28  equal_4_gs0_gs3_ga5_m1 (int i)
      29  {
      30    strcpy (ga5, "1234");
      31    const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5;
      32  
      33    A (snprintf (0, 0, "%s", p) == 0);
      34  }
      35  
      36  __attribute__ ((noclone, noinline, noipa)) void
      37  equal_4_gs0_gs3_ga5_0 (int i)
      38  {
      39    strcpy (ga5, "1234");
      40    const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5;
      41  
      42    A (snprintf (0, 0, "%s", p) == 4);
      43  }
      44  
      45  __attribute__ ((noclone, noinline, noipa)) void
      46  equal_4_gs0_gs3_ga5_p1 (int i)
      47  {
      48    strcpy (ga5, "1234");
      49    const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5;
      50  
      51    A (snprintf (0, 0, "%s", p) == 3);
      52  }
      53  
      54  
      55  __attribute__ ((noclone, noinline, noipa)) void
      56  equal_4_gs0_ga5_gs3_m1 (int i)
      57  {
      58    strcpy (ga5, "1234");
      59    const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3;
      60  
      61    A (snprintf (0, 0, "%s", p) == 0);
      62  }
      63  
      64  __attribute__ ((noclone, noinline, noipa)) void
      65  equal_4_gs0_ga5_gs3_0 (int i)
      66  {
      67    strcpy (ga5, "1234");
      68    const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3;
      69  
      70    A (snprintf (0, 0, "%s", p) == 3);
      71  }
      72  
      73  __attribute__ ((noclone, noinline, noipa)) void
      74  equal_4_gs0_ga5_gs3_p1 (int i)
      75  {
      76    strcpy (ga5, "1234");
      77    const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3;
      78  
      79    A (snprintf (0, 0, "%s", p) == 4);
      80  }
      81  
      82  
      83  __attribute__ ((noclone, noinline, noipa)) void
      84  equal_4_ga5_gs0_gs3_m1 (int i)
      85  {
      86    strcpy (ga5, "1234");
      87    const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3;
      88  
      89    A (snprintf (0, 0, "%s", p) == 4);
      90  }
      91  
      92  __attribute__ ((noclone, noinline, noipa)) void
      93  equal_4_ga5_gs0_gs3_0 (int i)
      94  {
      95    strcpy (ga5, "1234");
      96    const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3;
      97  
      98    A (snprintf (0, 0, "%s", p) == 3);
      99  }
     100  
     101  __attribute__ ((noclone, noinline, noipa)) void
     102  equal_4_ga5_gs0_gs3_p1 (int i)
     103  {
     104    strcpy (ga5, "1234");
     105    const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3;
     106  
     107    A (snprintf (0, 0, "%s", p) == 0);
     108  }
     109  
     110  
     111  __attribute__ ((noclone, noinline, noipa)) void
     112  equal_4_ga5_gs3_gs0_m1 (int i)
     113  {
     114    strcpy (ga5, "1234");
     115    const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0;
     116  
     117    A (snprintf (0, 0, "%s", p) == 4);
     118  }
     119  
     120  __attribute__ ((noclone, noinline, noipa)) void
     121  equal_4_ga5_gs3_gs0_0 (int i)
     122  {
     123    strcpy (ga5, "1234");
     124    const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0;
     125  
     126    A (snprintf (0, 0, "%s", p) == 0);
     127  }
     128  
     129  __attribute__ ((noclone, noinline, noipa)) void
     130  equal_4_ga5_gs3_gs0_p1 (int i)
     131  {
     132    strcpy (ga5, "1234");
     133    const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0;
     134  
     135    A (snprintf (0, 0, "%s", p) == 3);
     136  }
     137  
     138  
     139  __attribute__ ((noclone, noinline, noipa)) void
     140  equal_4_gs3_gs0_ga5_m1 (int i)
     141  {
     142    strcpy (ga5, "1234");
     143    const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5;
     144  
     145    A (snprintf (0, 0, "%s", p) == 3);
     146  }
     147  
     148  __attribute__ ((noclone, noinline, noipa)) void
     149  equal_4_gs3_gs0_ga5_0 (int i)
     150  {
     151    strcpy (ga5, "1234");
     152    const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5;
     153  
     154    A (snprintf (0, 0, "%s", p) == 4);
     155  }
     156  
     157  __attribute__ ((noclone, noinline, noipa)) void
     158  equal_4_gs3_gs0_ga5_p1 (int i)
     159  {
     160    strcpy (ga5, "1234");
     161    const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5;
     162  
     163    A (snprintf (0, 0, "%s", p) == 0);
     164  }
     165  
     166  
     167  /* Similar to the above but with memcpy creating a string at least
     168     four characters long, and the address of the NUL character.  */
     169  
     170  __attribute__ ((noclone, noinline, noipa)) void
     171  min_4_gc_gs3_ga5_m1 (int i)
     172  {
     173    gc = 0;
     174    memcpy (ga5, "1234", 4);
     175    const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5;
     176  
     177    A (snprintf (0, 0, "%s", p) == 0);
     178  }
     179  
     180  __attribute__ ((noclone, noinline, noipa)) void
     181  min_4_gc_gs3_ga5_0 (int i)
     182  {
     183    gc = 0;
     184    memcpy (ga5, "1234", 4);
     185    const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5;
     186  
     187    A (snprintf (0, 0, "%s", p) == 4);
     188  }
     189  
     190  __attribute__ ((noclone, noinline, noipa)) void
     191  min_4_gc_gs3_ga5_p1 (int i)
     192  {
     193    gc = 0;
     194    memcpy (ga5, "1234", 4);
     195    const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5;
     196  
     197    A (snprintf (0, 0, "%s", p) == 3);
     198  }
     199  
     200  
     201  __attribute__ ((noclone, noinline, noipa)) void
     202  min_4_gc_ga5_gs3_m1 (int i)
     203  {
     204    gc = 0;
     205    memcpy (ga5, "1234", 4);
     206    const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3;
     207  
     208    A (snprintf (0, 0, "%s", p) == 0);
     209  }
     210  
     211  __attribute__ ((noclone, noinline, noipa)) void
     212  min_4_gc_ga5_gs3_0 (int i)
     213  {
     214    gc = 0;
     215    memcpy (ga5, "1234", 4);
     216    const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3;
     217  
     218    A (snprintf (0, 0, "%s", p) == 3);
     219  }
     220  
     221  __attribute__ ((noclone, noinline, noipa)) void
     222  min_4_gc_ga5_gs3_p1 (int i)
     223  {
     224    gc = 0;
     225    memcpy (ga5, "1234", 4);
     226    const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3;
     227  
     228    A (snprintf (0, 0, "%s", p) == 4);
     229  }
     230  
     231  
     232  __attribute__ ((noclone, noinline, noipa)) void
     233  min_4_ga5_gc_gs3_m1 (int i)
     234  {
     235    gc = 0;
     236    memcpy (ga5, "1234", 4);
     237    const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3;
     238  
     239    A (snprintf (0, 0, "%s", p) == 4);
     240  }
     241  
     242  __attribute__ ((noclone, noinline, noipa)) void
     243  min_4_ga5_gc_gs3_0 (int i)
     244  {
     245    gc = 0;
     246    memcpy (ga5, "1234", 4);
     247    const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3;
     248  
     249    A (snprintf (0, 0, "%s", p) == 3);
     250  }
     251  
     252  __attribute__ ((noclone, noinline, noipa)) void
     253  min_4_ga5_gc_gs3_p1 (int i)
     254  {
     255    gc = 0;
     256    memcpy (ga5, "1234", 4);
     257    const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3;
     258  
     259    A (snprintf (0, 0, "%s", p) == 0);
     260  }
     261  
     262  
     263  __attribute__ ((noclone, noinline, noipa)) void
     264  min_4_ga5_gs3_gc_m1 (int i)
     265  {
     266    gc = 0;
     267    memcpy (ga5, "1234", 4);
     268    const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc;
     269  
     270    A (snprintf (0, 0, "%s", p) == 4);
     271  }
     272  
     273  __attribute__ ((noclone, noinline, noipa)) void
     274  min_4_ga5_gs3_gc_0 (int i)
     275  {
     276    gc = 0;
     277    memcpy (ga5, "1234", 4);
     278    const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc;
     279  
     280    A (snprintf (0, 0, "%s", p) == 0);
     281  }
     282  
     283  __attribute__ ((noclone, noinline, noipa)) void
     284  min_4_ga5_gs3_gc_p1 (int i)
     285  {
     286    gc = 0;
     287    memcpy (ga5, "1234", 4);
     288    const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc;
     289  
     290    A (snprintf (0, 0, "%s", p) == 3);
     291  }
     292  
     293  
     294  __attribute__ ((noclone, noinline, noipa)) void
     295  min_4_gs3_gc_ga5_m1 (int i)
     296  {
     297    gc = 0;
     298    memcpy (ga5, "1234", 4);
     299    const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5;
     300  
     301    A (snprintf (0, 0, "%s", p) == 3);
     302  }
     303  
     304  __attribute__ ((noclone, noinline, noipa)) void
     305  min_4_gs3_gc_ga5_0 (int i)
     306  {
     307    gc = 0;
     308    memcpy (ga5, "1234", 4);
     309    const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5;
     310  
     311    A (snprintf (0, 0, "%s", p) == 4);
     312  }
     313  
     314  __attribute__ ((noclone, noinline, noipa)) void
     315  min_4_gs3_gc_ga5_p1 (int i)
     316  {
     317    gc = 0;
     318    memcpy (ga5, "1234", 4);
     319    const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5;
     320  
     321    A (snprintf (0, 0, "%s", p) == 0);
     322  }
     323  
     324  
     325  int main (void)
     326  {
     327    equal_4_gs0_gs3_ga5_m1 (-1);
     328    equal_4_gs0_gs3_ga5_0  ( 0);
     329    equal_4_gs0_gs3_ga5_p1 (+1);
     330  
     331    equal_4_gs0_ga5_gs3_m1 (-1);
     332    equal_4_gs0_ga5_gs3_0  ( 0);
     333    equal_4_gs0_ga5_gs3_p1 (+1);
     334  
     335    equal_4_ga5_gs0_gs3_m1 (-1);
     336    equal_4_ga5_gs0_gs3_0  ( 0);
     337    equal_4_ga5_gs0_gs3_p1 (+1);
     338  
     339    equal_4_ga5_gs3_gs0_m1 (-1);
     340    equal_4_ga5_gs3_gs0_0  ( 0);
     341    equal_4_ga5_gs3_gs0_p1 (+1);
     342  
     343    equal_4_gs3_gs0_ga5_m1 (-1);
     344    equal_4_gs3_gs0_ga5_0  ( 0);
     345    equal_4_gs3_gs0_ga5_p1 (+1);
     346  
     347    /* Same as aabove but with memcpy creating a string at least four
     348       characters long.  */
     349    memset (ga5, 0, sizeof ga5);
     350    min_4_gc_gs3_ga5_m1 (-1);
     351    memset (ga5, 0, sizeof ga5);
     352    min_4_gc_gs3_ga5_0  ( 0);
     353    memset (ga5, 0, sizeof ga5);
     354    min_4_gc_gs3_ga5_p1 (+1);
     355  
     356    memset (ga5, 0, sizeof ga5);
     357    min_4_gc_ga5_gs3_m1 (-1);
     358    memset (ga5, 0, sizeof ga5);
     359    min_4_gc_ga5_gs3_0  ( 0);
     360    memset (ga5, 0, sizeof ga5);
     361    min_4_gc_ga5_gs3_p1 (+1);
     362  
     363    memset (ga5, 0, sizeof ga5);
     364    min_4_ga5_gc_gs3_m1 (-1);
     365    memset (ga5, 0, sizeof ga5);
     366    min_4_ga5_gc_gs3_0  ( 0);
     367    memset (ga5, 0, sizeof ga5);
     368    min_4_ga5_gc_gs3_p1 (+1);
     369  
     370    memset (ga5, 0, sizeof ga5);
     371    min_4_ga5_gs3_gc_m1 (-1);
     372    memset (ga5, 0, sizeof ga5);
     373    min_4_ga5_gs3_gc_0  ( 0);
     374    memset (ga5, 0, sizeof ga5);
     375    min_4_ga5_gs3_gc_p1 (+1);
     376  
     377    memset (ga5, 0, sizeof ga5);
     378    min_4_gs3_gc_ga5_m1 (-1);
     379    memset (ga5, 0, sizeof ga5);
     380    min_4_gs3_gc_ga5_0  ( 0);
     381    memset (ga5, 0, sizeof ga5);
     382    min_4_gs3_gc_ga5_p1 (+1);
     383  }