1  /* PR tree-optimization/79327 - wrong code at -O2 and -fprintf-return-value
       2     { dg-do compile }
       3     { dg-options "-O2 -fdump-tree-optimized" } */
       4  
       5  #define CAT(s, n)   s ## n
       6  #define FAIL(line)  CAT (failure_on_line_, line)
       7  
       8  /* Emit a call to a function named failure_on_line_NNN when EXPR is false.  */
       9  #define ASSERT(expr)				\
      10    do {						\
      11      extern void FAIL (__LINE__)(void);		\
      12      if (!(expr)) FAIL (__LINE__)();		\
      13    } while (0)
      14  
      15  #define KEEP(line)  CAT (keep_call_on_line_, line)
      16  
      17  /* Emit a call to a function named keep_call_on_line_NNN when EXPR is true.
      18     Used to verify that the expression need not be the only one that holds.  */
      19  #define ASSERT_MAYBE(expr)			\
      20    do {						\
      21      extern void KEEP (__LINE__)(void);		\
      22      if (expr) KEEP (__LINE__)();		\
      23    } while (0)
      24  
      25  void test_hho_cst (void)
      26  {
      27    ASSERT (1 == __builtin_snprintf (0, 0, "%#.1hho", 0));
      28    ASSERT (2 == __builtin_snprintf (0, 0, "%#.2hho", 0));
      29  
      30    ASSERT (2 == __builtin_snprintf (0, 0, "%#.1hho", 1));
      31    ASSERT (2 == __builtin_snprintf (0, 0, "%#.2hho", 1));
      32    ASSERT (3 == __builtin_snprintf (0, 0, "%#.3hho", 1));
      33  }
      34  
      35  int test_hho_var (int i)
      36  {
      37    int n = __builtin_snprintf (0, 0, "%#hho", i);
      38  
      39    ASSERT (0 < n && n < 5);
      40  
      41    ASSERT_MAYBE (1 == n);
      42    ASSERT_MAYBE (2 == n);
      43    ASSERT_MAYBE (3 == n);
      44    ASSERT_MAYBE (4 == n);
      45  
      46    return n;
      47  }
      48  
      49  int test_ho_var (int i)
      50  {
      51    int n = __builtin_snprintf (0, 0, "%#ho", i);
      52  
      53    ASSERT (0 < n && n < 8);
      54  
      55    ASSERT_MAYBE (1 == n);
      56    ASSERT_MAYBE (2 == n);
      57    ASSERT_MAYBE (3 == n);
      58    ASSERT_MAYBE (4 == n);
      59    ASSERT_MAYBE (5 == n);
      60    ASSERT_MAYBE (6 == n);
      61    ASSERT_MAYBE (7 == n);
      62  
      63    return n;
      64  }
      65  
      66  int test_o_var (int i)
      67  {
      68    int n = __builtin_snprintf (0, 0, "%#o", i);
      69  
      70    ASSERT (0 < n && n < 13);
      71  
      72    ASSERT_MAYBE (1 == n);
      73    ASSERT_MAYBE (2 == n);
      74    ASSERT_MAYBE (3 == n);
      75    ASSERT_MAYBE (4 == n);
      76    ASSERT_MAYBE (5 == n);
      77    ASSERT_MAYBE (6 == n);
      78    ASSERT_MAYBE (7 == n);
      79    /* Below will be optimized out for 16-bit int.  */
      80    ASSERT_MAYBE (8 == n);
      81    ASSERT_MAYBE (9 == n);
      82    ASSERT_MAYBE (10 == n);
      83    ASSERT_MAYBE (11 == n);
      84    ASSERT_MAYBE (12 == n);
      85  
      86    return n;
      87  }
      88  
      89  void test_hhx_cst (void)
      90  {
      91    ASSERT (1 == __builtin_snprintf (0, 0, "%#.1hhx", 0));
      92    ASSERT (2 == __builtin_snprintf (0, 0, "%#.2hhx", 0));
      93  
      94    ASSERT (3 == __builtin_snprintf (0, 0, "%#.1hhx", 1));
      95    ASSERT (4 == __builtin_snprintf (0, 0, "%#.2hhx", 1));
      96    ASSERT (5 == __builtin_snprintf (0, 0, "%#.3hhx", 1));
      97  }
      98  
      99  int test_hhx_var (int i)
     100  {
     101    int n = __builtin_snprintf (0, 0, "%#hhx", i);
     102  
     103    ASSERT (0 < n && n < 5);
     104  
     105    ASSERT_MAYBE (1 == n);
     106    ASSERT_MAYBE (2 == n);
     107    ASSERT_MAYBE (3 == n);
     108    ASSERT_MAYBE (4 == n);
     109  
     110    return n;
     111  }
     112  
     113  void test_hx_cst (void)
     114  {
     115    ASSERT (1 == __builtin_snprintf (0, 0, "%#.1hx", 0));
     116    ASSERT (2 == __builtin_snprintf (0, 0, "%#.2hx", 0));
     117  
     118    ASSERT (3 == __builtin_snprintf (0, 0, "%#.1hx", 1));
     119    ASSERT (4 == __builtin_snprintf (0, 0, "%#.2hx", 1));
     120    ASSERT (5 == __builtin_snprintf (0, 0, "%#.3hx", 1));
     121  }
     122  
     123  int test_hx_var (int i)
     124  {
     125    int n = __builtin_snprintf (0, 0, "%#hx", i);
     126  
     127    ASSERT (0 < n && n < 7);
     128  
     129    ASSERT_MAYBE (1 == n);
     130    ASSERT_MAYBE (2 == n);
     131    ASSERT_MAYBE (3 == n);
     132    ASSERT_MAYBE (4 == n);
     133    ASSERT_MAYBE (5 == n);
     134    ASSERT_MAYBE (6 == n);
     135  
     136    return n;
     137  }
     138  
     139  int test_x_var (int i)
     140  {
     141    int n = __builtin_snprintf (0, 0, "%#x", i);
     142  
     143    ASSERT (0 < n && n < 11);
     144  
     145    ASSERT_MAYBE (1 == n);
     146    ASSERT_MAYBE (2 == n);
     147    ASSERT_MAYBE (3 == n);
     148    ASSERT_MAYBE (4 == n);
     149    ASSERT_MAYBE (5 == n);
     150    ASSERT_MAYBE (6 == n);
     151    /* Below will be optimized out for 16-bit int.  */
     152    ASSERT_MAYBE (7 == n);
     153    ASSERT_MAYBE (8 == n);
     154    ASSERT_MAYBE (9 == n);
     155    ASSERT_MAYBE (10 == n);
     156  
     157    return n;
     158  }
     159  
     160  /* { dg-final { scan-tree-dump-not "failure_on_line" "optimized"} }
     161     { dg-final { scan-tree-dump-times "keep_call_on_line" 43 "optimized" { target { ! int16 } } } }
     162     { dg-final { scan-tree-dump-times "keep_call_on_line" 34 "optimized" { target int16 } } } */