1  void test_direct (void)
       2  {
       3    test_direct (); /* { dg-warning "infinite recursion" } */
       4  }
       5  
       6  void test_guarded (int flag)
       7  {
       8    if (flag)
       9      test_guarded (flag); /* { dg-warning "infinite recursion" } */
      10  }
      11  
      12  void test_flipped_guard (int flag)
      13  {
      14    if (flag)
      15      test_guarded (!flag); /* { dg-bogus "infinite recursion" } */
      16  }
      17  
      18  void test_param_variant (int depth)
      19  {
      20    if (depth > 0)
      21      test_param_variant (depth - 1); /* { dg-bogus "infinite recursion" } */
      22  }
      23  
      24  void test_unguarded_param_variant (int depth)
      25  {
      26    /* We fail to report this: we see that depth is being decremented,
      27       but don't notice that every path through the function is
      28       recursing.  */
      29    test_unguarded_param_variant (depth - 1); /* { dg-warning "infinite recursion" "TODO" { xfail *-*-* } } */
      30  }
      31  
      32  int g;
      33  
      34  void test_global_variant ()
      35  {
      36    if (g-- > 0)
      37      test_global_variant (); /* { dg-bogus "infinite recursion" } */
      38  }
      39  
      40  /* This is a bounded recursion, as "n" is decremented before recursing... */
      41  
      42  int test_while_do_predecrement_param (int n)
      43  {
      44    int x = 0;
      45    while (n)
      46      x += test_while_do_predecrement_param (--n); /* { dg-bogus "infinite recursion" } */
      47    return x;
      48  }
      49  
      50  /* ...whereas this one is unbounded, as "n" is decremented *after* the
      51     recursive call, and so is repeatedly called with the same value.  */
      52  
      53  int test_while_do_postdecrement_param (int n)
      54  {
      55    int x = 0;
      56    while (n)
      57      x += test_while_do_postdecrement_param (n--); /* { dg-warning "infinite recursion" } */
      58    return x;
      59  }
      60  /* This is a bounded recursion, as "n" is decremented before recursing... */
      61  
      62  int test_do_while_predecrement_param (int n)
      63  {
      64    int x = 0;
      65    do
      66      x += test_do_while_predecrement_param (--n); /* { dg-bogus "infinite recursion" } */
      67    while (--n);
      68    return x;
      69  }
      70  
      71  /* ...whereas this one is unbounded, as "n" is decremented *after* the
      72     recursive call, and so is repeatedly called with the same value.  */
      73  
      74  int test_do_while_postdecrement_param (int n)
      75  {
      76    int x = 0;
      77    do
      78      x += test_do_while_postdecrement_param (n--); /* { dg-warning "infinite recursion" } */
      79    while (--n);
      80    return x;
      81  }
      82  
      83  /* Various cases of decrementing "n" as the recursion proceeds where
      84     not every path recurses, but we're not actually checking "n", so
      85     if "flag" is true it's an infinite recursion.  */
      86  
      87  void test_partially_guarded_postdecrement (int flag, int n)
      88  {
      89    /* We catch this; the "n--" means we recurse with the
      90       same value for the 2nd param.  */
      91    if (flag) /* { dg-message "when 'flag != 0'" } */
      92      test_partially_guarded_postdecrement (flag, n--); /* { dg-warning "infinite recursion" } */
      93  }
      94  
      95  void test_partially_guarded_predecrement (int flag, int n)
      96  {
      97    /* We fail to report this; we see that "n" is changing,
      98       though it isn't relevant to whether we recurse.  */
      99    if (flag)
     100      test_partially_guarded_predecrement (flag, --n); /* { dg-warning "infinite recursion" "TODO" { xfail *-*-* } } */
     101  }
     102  
     103  void test_partially_guarded_subtract (int flag, int n)
     104  {
     105    /* We fail to report this; we see that "n" is changing,
     106       though it isn't relevant to whether we recurse.  */
     107    if (flag)
     108      test_partially_guarded_subtract (flag, n - 1); /* { dg-warning "infinite recursion" "TODO" { xfail *-*-* } } */
     109  }