(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wstringop-truncation.c
       1  /* PR tree-optimization/84468 - Inconsistent -Wstringop-truncation warnings
       2     with -O2
       3     { dg-do compile }
       4     { dg-options "-O2 -Wstringop-truncation -ftrack-macro-expansion=0 -g" }  */
       5  
       6  #define strncpy __builtin_strncpy
       7  
       8  struct A
       9  {
      10    char a[4];
      11  };
      12  
      13  void no_pred_succ_lit (struct A *p)
      14  {
      15    /* The following is folded early on, before the strncpy statement
      16       has a basic block.  Verify that the case is handled gracefully
      17       (i.e., there's no assumption that the statement does have
      18       a basic block).  */
      19    strncpy (p->a, "1234", sizeof p->a - 1);    /* { dg-warning "\\\[-Wstringop-truncation" } */
      20  }
      21  
      22  /* Verify a strncpy call in a basic block with no predecessor or
      23     successor.  */
      24  void no_pred_succ (struct A *p, const struct A *q)
      25  {
      26    strncpy (p->a, q->a, sizeof p->a - 1);      /* { dg-warning "\\\[-Wstringop-truncation" } */
      27  }
      28  
      29  
      30  /* Verify a strncpy call in a basic block with no successor.  */
      31  void no_succ (struct A *p, const struct A *q)
      32  {
      33    if (q->a)
      34      strncpy (p->a, q->a, sizeof p->a - 1);    /* { dg-warning "\\\[-Wstringop-truncation" } */
      35  }
      36  
      37  /* Verify a strncpy call in a basic block with nul assignment in
      38     a successor block.  */
      39  void succ (struct A *p, const struct A *q)
      40  {
      41    /* Verify that the assignment suppresses the warning for the conditional
      42       strcnpy call.  The conditional should be folded to true since the
      43       address of an array can never be null (see bug 84470).  */
      44    if (q->a)
      45      strncpy (p->a, q->a, sizeof p->a - 1);    /* { dg-bogus "\\\[-Wstringop-truncation" } */
      46  
      47    p->a[sizeof p->a - 1] = 0;
      48  }
      49  
      50  
      51  void succ_2 (struct A *p, const struct A *q, int i)
      52  {
      53    /* Same as above but with a conditional that cannot be eliminated.  */
      54    if (i < 0)
      55      strncpy (p->a, q->a, sizeof p->a - 1);    /* { dg-bogus "\\\[-Wstringop-truncation" } */
      56  
      57    p->a[sizeof p->a - 1] = 0;
      58  }
      59  
      60  
      61  /* Verify a strncpy call in a basic block with nul assignment in
      62     the next successor block.  */
      63  int next_succ (struct A *p, const struct A *q, int i, int j)
      64  {
      65    /* Same as above but with a nested conditionals with else clauses.  */
      66    if (i < 0)
      67      {
      68        if (j < 0)
      69  	strncpy (p->a, q->a, sizeof p->a - 1);    /* { dg-bogus "\\\[-Wstringop-truncation" } */
      70      }
      71    else
      72      __builtin_strcpy (p->a, q->a);
      73  
      74    p->a[sizeof p->a - 1] = 0;
      75    return 0;
      76  }
      77  
      78  
      79  int next_succ_1 (struct A *p, const struct A *q, int i, int j)
      80  {
      81    /* Same as above but with a nested conditionals with else clauses.  */
      82    if (i < 0)
      83      {
      84        if (j < 0)
      85  	strncpy (p->a, q->a, sizeof p->a - 1);    /* { dg-bogus "\\\[-Wstringop-truncation" } */
      86        else
      87  	strncpy (p->a, q->a, sizeof p->a - 2);    /* { dg-bogus "\\\[-Wstringop-truncation" } */
      88      }
      89  
      90    p->a[sizeof p->a - 2] = 0;
      91    return 1;
      92  }
      93  
      94  
      95  int next_succ_2 (struct A *p, const struct A *q, int i, int j)
      96  {
      97    /* Same as above but with a nested conditionals with else clauses.  */
      98    if (i < 0)
      99      {
     100        if (j < 0)
     101  	strncpy (p->a, q->a, sizeof p->a - 1);    /* { dg-bogus "\\\[-Wstringop-truncation" } */
     102        else
     103  	strncpy (p->a, q->a, sizeof p->a - 2);    /* { dg-bogus "\\\[-Wstringop-truncation" } */
     104      }
     105    else
     106      __builtin_strcpy (p->a, q->a);
     107  
     108    p->a[sizeof p->a - 2] = 0;
     109    return 2;
     110  }
     111  
     112  
     113  void cond_succ_warn (struct A *p, const struct A *q, int i)
     114  {
     115    /* Verify that a conditional assignment doesn't suppress the warning.  */
     116    strncpy (p->a, q->a, sizeof p->a - 1);      /* { dg-warning "\\\[-Wstringop-truncation" } */
     117  
     118    if (i < 0)
     119      p->a[sizeof p->a - 1] = 0;
     120  }
     121  
     122  void cond_succ_nowarn (struct A *p, const struct A *q)
     123  {
     124    /* Verify that distinct but provably equivalent conditionals are
     125       recognized and don't trigger the warning.  */
     126    if (p != q)
     127      strncpy (p->a, q->a, sizeof p->a - 1);
     128  
     129    if (p->a != q->a)
     130      p->a[sizeof p->a - 1] = 0;
     131  }