(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
attr-const-1.c
       1  /* Verify that we handle functions with __attribute__ ((const)) correctly.  */
       2  
       3  #include "analyzer-decls.h"
       4  
       5  extern int nonconst_fn (int);
       6  
       7  extern int const_fn_0 () __attribute__ ((const));
       8  extern int const_fn_1 (int) __attribute__ ((const));
       9  extern int const_fn_2 (int, int) __attribute__ ((const));
      10  extern int const_fn_3 (int, int, int) __attribute__ ((const));
      11  extern int const_fn_variadic (int, ...) __attribute__ ((const));
      12  
      13  /* Verify that functions without __attribute__ ((const)) have a different
      14     result each time.  */
      15  
      16  void test_nonconst_fn (int x, int y)
      17  {
      18    int x_1 = nonconst_fn (x);
      19    int x_2 = nonconst_fn (x);
      20    int y_1 = nonconst_fn (y);
      21    int y_2 = nonconst_fn (y);
      22    __analyzer_eval (x_1 == x_2); /* { dg-warning "UNKNOWN" } */
      23    __analyzer_eval (y_1 == y_2); /* { dg-warning "UNKNOWN" } */
      24    __analyzer_eval (x_1 == y_1); /* { dg-warning "UNKNOWN" } */
      25  }
      26  
      27  /* Verify functions with __attribute__ ((const)) have the same result
      28     for the same arguments.  */
      29  
      30   /* 0 args.  */
      31  
      32  extern int other_const_fn_0 () __attribute__ ((const));
      33  
      34  void test_const_fn_0 (void)
      35  {
      36    int a = const_fn_0 ();
      37    int b = const_fn_0 ();
      38    int c = other_const_fn_0 ();
      39    int d = other_const_fn_0 ();
      40    __analyzer_eval (a == b); /* { dg-warning "TRUE" } */
      41    __analyzer_eval (c == d); /* { dg-warning "TRUE" } */
      42    __analyzer_eval (a == c); /* { dg-warning "UNKNOWN" } */
      43  }
      44  
      45  /* 1 arg.  */
      46  
      47  void test_const_fn_1 (int x, int y)
      48  {
      49    int x_1 = const_fn_1 (x);
      50    int x_2 = const_fn_1 (x);
      51    int y_1 = const_fn_1 (y);
      52    int y_2 = const_fn_1 (y);
      53    __analyzer_eval (x_1 == x_2); /* { dg-warning "TRUE" } */
      54    __analyzer_eval (y_1 == y_2); /* { dg-warning "TRUE" } */
      55    __analyzer_eval (x_1 == y_1); /* { dg-warning "UNKNOWN" } */
      56  }
      57  
      58  /* 2 args.  */
      59  
      60  void test_const_fn_2 (int x, int y, int p, int q)
      61  {
      62    int xy_1 = const_fn_2 (x, y);
      63    int xy_2 = const_fn_2 (x, y);
      64    int pq_1 = const_fn_2 (p, q);
      65    int pq_2 = const_fn_2 (p, q);
      66    __analyzer_eval (xy_1 == xy_2); /* { dg-warning "TRUE" } */
      67    __analyzer_eval (pq_1 == pq_2); /* { dg-warning "TRUE" } */
      68    __analyzer_eval (xy_1 == pq_1); /* { dg-warning "UNKNOWN" } */
      69  }
      70  
      71  /* We don't handle above 2 args.  */
      72  
      73  void test_const_fn_3 (int x, int y, int z, int p, int q, int r)
      74  {
      75    int xyz_1 = const_fn_3 (x, y, z);
      76    int xyz_2 = const_fn_3 (x, y, z);
      77    int pqr_1 = const_fn_3 (p, q, r);
      78    int pqr_2 = const_fn_3 (p, q, r);
      79    __analyzer_eval (xyz_1 == xyz_2); /* { dg-warning "UNKNOWN" } */
      80    __analyzer_eval (pqr_1 == pqr_2); /* { dg-warning "UNKNOWN" } */
      81    __analyzer_eval (xyz_1 == pqr_1); /* { dg-warning "UNKNOWN" } */
      82  }
      83  
      84  /* Variadic fn, with various numbers of extra args.  */
      85  
      86  void test_const_fn_variadic (int x, int y, int z, int p, int q, int r)
      87  {
      88    /* 0 extra args, for 1 arg in total.  */
      89    int x_1 = const_fn_variadic (x);
      90    int x_2 = const_fn_variadic (x);
      91    int p_1 = const_fn_variadic (p);
      92    int p_2 = const_fn_variadic (p);
      93    __analyzer_eval (x_1 == x_2); /* { dg-warning "TRUE" } */
      94    __analyzer_eval (p_1 == p_2); /* { dg-warning "TRUE" } */
      95    __analyzer_eval (x_1 == p_1); /* { dg-warning "UNKNOWN" } */
      96  
      97    /* 1 extra arg, for 2 args in total.  */
      98    int xy_1 = const_fn_variadic (x, y);
      99    int xy_2 = const_fn_variadic (x, y);
     100    int pq_1 = const_fn_variadic (p, q);
     101    int pq_2 = const_fn_variadic (p, q);
     102    __analyzer_eval (xy_1 == xy_2); /* { dg-warning "TRUE" } */
     103    __analyzer_eval (pq_1 == pq_2); /* { dg-warning "TRUE" } */
     104    __analyzer_eval (xy_1 == pq_1); /* { dg-warning "UNKNOWN" } */
     105    __analyzer_eval (x_1 == xy_1); /* { dg-warning "UNKNOWN" } */
     106    __analyzer_eval (p_1 == pq_1); /* { dg-warning "UNKNOWN" } */
     107  
     108    /* Above that, we don't track results.  */
     109    int xyz_1 = const_fn_variadic (x, y, z);
     110    int xyz_2 = const_fn_variadic (x, y, z);
     111    int pqr_1 = const_fn_variadic (p, q, r);
     112    int pqr_2 = const_fn_variadic (p, q, r);
     113    __analyzer_eval (xyz_1 == xyz_2); /* { dg-warning "UNKNOWN" } */
     114    __analyzer_eval (pqr_1 == pqr_2); /* { dg-warning "UNKNOWN" } */
     115    __analyzer_eval (xyz_1 == x_1); /* { dg-warning "UNKNOWN" } */
     116    __analyzer_eval (xyz_1 == xy_1); /* { dg-warning "UNKNOWN" } */
     117    __analyzer_eval (xyz_1 == pqr_1); /* { dg-warning "UNKNOWN" } */
     118  }
     119  
     120  /* Builtins with __attribute__ ((const)).  */
     121  
     122  void test_builtin_isascii (int x, int y)
     123  {
     124    int x_1 = __builtin_isascii (x);
     125    int x_2 = __builtin_isascii (x);
     126    int y_1 = __builtin_isascii (y);
     127    int y_2 = __builtin_isascii (y);
     128    __analyzer_eval (x_1 == x_2); /* { dg-warning "TRUE" } */
     129    __analyzer_eval (y_1 == y_2); /* { dg-warning "TRUE" } */
     130    __analyzer_eval (x_1 == y_1); /* { dg-warning "UNKNOWN" } */
     131  }
     132  
     133  void test_builtin_popcount (unsigned x, unsigned y)
     134  {
     135    unsigned x_1 = __builtin_popcount (x);
     136    unsigned x_2 = __builtin_popcount (x);
     137    unsigned y_1 = __builtin_popcount (y);
     138    unsigned y_2 = __builtin_popcount (y);
     139    __analyzer_eval (x_1 == x_2); /* { dg-warning "TRUE" } */
     140    __analyzer_eval (y_1 == y_2); /* { dg-warning "TRUE" } */
     141    __analyzer_eval (x_1 == y_1); /* { dg-warning "UNKNOWN" } */
     142  }
     143  
     144  void test_loop (void)
     145  {
     146    for (int i = 0; i < 100; i++)
     147      {
     148        int iter_val_a = const_fn_1 (i);
     149        int iter_val_b = const_fn_1 (i);
     150        __analyzer_eval (iter_val_a == iter_val_b); /* { dg-warning "TRUE" } */
     151      }
     152  }