(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
loop-0-up-to-n-by-1-with-iter-obj.c
       1  #include <stdlib.h>
       2  
       3  #include "analyzer-decls.h"
       4  
       5  struct iter
       6  {
       7    int start;
       8    int end;
       9    int step;
      10    int val;
      11  };
      12  
      13  struct iter *  __attribute__((noinline))
      14  iter_new (int start, int end, int step)
      15  {
      16    struct iter *it = (struct iter *)malloc (sizeof (struct iter));
      17    if (!it)
      18      abort ();
      19    it->start = start;
      20    it->end = end;
      21    it->step = step;
      22    it->val = start;
      23    return it;
      24  }
      25  
      26  int __attribute__((noinline))
      27  iter_done_p (struct iter *it)
      28  {
      29    return it->val >= it->end;
      30  }
      31  
      32  void __attribute__((noinline))
      33  iter_next (struct iter *it)
      34  {
      35    it->val += it->step;
      36  }
      37  
      38  /* Example of an iterator object, to see how well we cope with a well-disguised
      39     iteration from 0 to n with a step of 1.  */
      40  
      41  void test(int n)
      42  {
      43    __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
      44  
      45    struct iter *it = iter_new (0, n, 1);
      46    while (!iter_done_p (it))
      47      {
      48        __analyzer_eval (it->val < n); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
      49        /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
      50        /* TODO(xfail^^^): ideally we ought to figure out i > 0 after 1st iteration.  */
      51  
      52        __analyzer_eval (it->val == 0); /* { dg-warning "TRUE" "true on 1st iter" } */
      53        /* { dg-warning "UNKNOWN" "unknown" { target *-*-* } .-1 } */
      54        /* TODO: should we ought to figure out i > 0 after 1st iteration?  */
      55  
      56        __analyzer_eval (it->val >= 0); /* { dg-warning "TRUE" } */
      57  
      58        __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
      59  
      60        iter_next (it);
      61      }
      62  
      63    __analyzer_eval (it->val >= n); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
      64    /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
      65  
      66    __analyzer_eval (it->val == n); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
      67    /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
      68    /* TODO(xfail^^^): it only figures out i >= 256, rather than i == 256.  */
      69  
      70    free (it);
      71  
      72    __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
      73  }