(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wstringop-overread-6.c
       1  /* Verify -Wstringop-overread is issued appropriately for calls to string
       2     functions at -O0 and without -Wall.
       3    { dg-do compile }
       4    { dg-options "-O0 -ftrack-macro-expansion=0" } */
       5  
       6  typedef __SIZE_TYPE__ size_t;
       7  
       8  #define S2 "12"
       9  #define S9 "123456789"
      10  
      11  // <libint.h> functions.
      12  
      13  char* gettext (const char *);
      14  
      15  // <stdio.h> functions.
      16  
      17  typedef struct FILE FILE;
      18  
      19  int fputs (const char*, FILE*);
      20  int fputs_unlocked (const char*, FILE*);
      21  
      22  int puts (const char*);
      23  int puts_unlocked (const char*);
      24  
      25  // <string.h> functions.
      26  
      27  void* memchr (const void*, int, size_t);
      28  int memcmp (const void*, const void*, size_t);
      29  void* memcpy (void*, const void*, size_t);
      30  void* mempcpy (void*, const void*, size_t);
      31  void* memmove (void*, const void*, size_t);
      32  
      33  char* strchr (const char*, int);
      34  char* strrchr (const char*, int);
      35  
      36  int strcmp (const char*, const char*);
      37  int strncmp (const char*, const char*, size_t);
      38  
      39  char* strcat (char*, const char*);
      40  char* stpcpy (char*, const char*);
      41  char* strcpy (char*, const char*);
      42  char* stpncpy (char*, const char*, size_t);
      43  char* strncpy (char*, const char*, size_t);
      44  char* strdup (const char*);
      45  char* strndup (const char*, size_t);
      46  
      47  char* strpbrk (const char*, const char*);
      48  size_t strcspn (const char*, const char*);
      49  size_t strspn (const char*, const char*);
      50  char* strstr (const char*, const char*);
      51  
      52  size_t strlen (const char*);
      53  size_t strnlen (const char*, size_t);
      54  
      55  
      56  extern void* malloc (size_t);
      57  
      58  void sink (void*);
      59  
      60  
      61  extern char *d;
      62  extern char a0[0];
      63  
      64  const char arr[7] = "abc\0def";
      65  
      66  /* Unterminated array at the end of ARR above.  */
      67  #define unterm (arr + __builtin_strlen (arr) + 1)
      68  
      69  /* Size of the unterminated array - 1.  */
      70  #define unterm_size (sizeof arr - __builtin_strlen (arr) - 1)
      71  
      72  const void* nowarn_memchr (int x)
      73  {
      74    const char *p1 = unterm;
      75    return memchr (p1, x, unterm_size);
      76  }
      77  
      78  const void* warn_memchr (int x)
      79  {
      80    const char *p1 = unterm;
      81    return memchr (p1, x, unterm_size + 1);       // { dg-warning "-Wstringop-overread" }
      82  }
      83  
      84  
      85  void* nowarn_memcpy (void)
      86  {
      87    const char *s = unterm;
      88    return memcpy (d, s, unterm_size);
      89  }
      90  
      91  void* warn_memcpy (void)
      92  {
      93    const char *s = unterm;
      94    /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform
      95       from defeating the warning (for now).  */
      96    return memcpy (d, s, unterm_size + 2 | 1);    // { dg-warning "-Wstringop-overread" }
      97  }
      98  
      99  
     100  void* nowarn_mempcpy (void)
     101  {
     102    const char *s = unterm;
     103    return mempcpy (d, s, unterm_size);
     104  }
     105  
     106  void* warn_mempcpy (void)
     107  {
     108    const char *s = unterm;
     109    /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform
     110       from defeating the warning (for now).  */
     111    return mempcpy (d, s, unterm_size + 2 | 1);   // { dg-warning "-Wstringop-overread" }
     112  }
     113  
     114  
     115  void* nowarn_memmove (void)
     116  {
     117    const char *s = unterm;
     118    return memmove (d, s, unterm_size);
     119  }
     120  
     121  void* warn_memmove (void)
     122  {
     123    const char *s = unterm;
     124    /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform
     125       from defeating the warning (for now).  */
     126    return memmove (d, s, unterm_size + 2);       // { dg-warning "-Wstringop-overread" }
     127  }
     128  
     129  
     130  int nowarn_memcmp_1 (const char *p2)
     131  {
     132    const char *p1 = unterm;
     133    return memcmp (p1, p2, unterm_size);
     134  }
     135  
     136  int warn_memcmp_1 (const char *p2)
     137  {
     138    const char *p1 = unterm;
     139    return memcmp (p1, p2, unterm_size + 1);      // { dg-warning "-Wstringop-overread" }
     140  }
     141  
     142  int nowarn_memcmp_2 (const char *p1)
     143  {
     144    const char *p2 = unterm;
     145    return memcmp (p1, p2, unterm_size);
     146  }
     147  
     148  int warn_memcmp_2 (const char *p1)
     149  {
     150    const char *p2 = unterm;
     151    return memcmp (p1, p2, unterm_size + 1);      // { dg-warning "-Wstringop-overread" }
     152  }
     153  
     154  
     155  void warn_strcat (void)
     156  {
     157    strcat (d, unterm);                   // { dg-warning "-Wstringop-overread" }
     158  }
     159  
     160  void warn_strcat_a0 (void)
     161  {
     162    strcat (d, a0);                       // { dg-warning "-Wstringop-overread" }
     163  }
     164  
     165  void warn_strcat_end (void)
     166  {
     167    const char *s = arr + sizeof arr;
     168    strcat (d, s);                        // { dg-warning "-Wstringop-overread" }
     169  }
     170  
     171  char* warn_stpcpy (void)
     172  {
     173    return stpcpy (d, unterm);            // { dg-warning "-Wstringop-overread" }
     174  }
     175  
     176  char* warn_stpcpy_a0 (void)
     177  {
     178    return stpcpy (d, a0);                // { dg-warning "-Wstringop-overread" }
     179  }
     180  
     181  char* warn_stpcpy_end (void)
     182  {
     183    const char *s = arr + sizeof arr;
     184    return stpcpy (d, s);                 // { dg-warning "-Wstringop-overread" }
     185  }
     186  
     187  char* warn_stpcpy_malloc0 (void)
     188  {
     189    char *s = malloc (0);
     190    sink (s);
     191    return stpcpy (d, s);                 // { dg-warning "-Wstringop-overread" }
     192  }
     193  
     194  
     195  void warn_strcpy (void)
     196  {
     197    strcpy (d, unterm);                   // { dg-warning "-Wstringop-overread" }
     198  }
     199  
     200  void warn_strcpy_a0 (void)
     201  {
     202    strcpy (d, a0);                       // { dg-warning "-Wstringop-overread" }
     203  }
     204  
     205  void warn_strcpy_end (void)
     206  {
     207    const char *s = arr + sizeof arr;
     208    strcpy (d, s);                        // { dg-warning "-Wstringop-overread" }
     209  }
     210  
     211  void warn_strcpy_malloc0 (void)
     212  {
     213    char *s = malloc (0);
     214    sink (s);
     215    strcpy (d, s);                        // { dg-warning "-Wstringop-overread" }
     216  }
     217  
     218  
     219  char* nowarn_stpncpy (void)
     220  {
     221    const char *s = unterm;
     222    return stpncpy (d, s, unterm_size);
     223  }
     224  
     225  char* warn_stpncpy (void)
     226  {
     227    const char *s = unterm;
     228    return stpncpy (d, s, unterm_size + 1);       // { dg-warning "-Wstringop-overread" }
     229  }
     230  
     231  char* warn_stpncpy_a0 (void)
     232  {
     233    return stpncpy (d, a0, 3);            // { dg-warning "-Wstringop-overread" }
     234  }
     235  
     236  char* warn_stpncpy_end (void)
     237  {
     238    const char *s = arr + sizeof arr;
     239    return stpncpy (d, s, sizeof arr);    // { dg-warning "-Wstringop-overread" }
     240  }
     241  
     242  
     243  void nowarn_strncpy (void)
     244  {
     245    const char *s = unterm;
     246    strncpy (d, s, unterm_size);
     247  }
     248  
     249  void warn_strncpy (void)
     250  {
     251    const char *s = unterm;
     252    strncpy (d, s, unterm_size + 1);      // { dg-warning "-Wstringop-overread" }
     253  }
     254  
     255  void warn_strncpy_a0 (void)
     256  {
     257    const char *s = a0;
     258    strncpy (d, s, sizeof arr);            // { dg-warning "-Wstringop-overread" }
     259  }
     260  
     261  void warn_strncpy_end (void)
     262  {
     263    const char *s = arr + sizeof arr;
     264    strncpy (d, s, sizeof arr);            // { dg-warning "-Wstringop-overread" }
     265  }
     266  
     267  
     268  int warn_strlen (void)
     269  {
     270    return strlen (unterm);               // { dg-warning "-Wstringop-overread" }
     271  }
     272  
     273  int warn_strlen_a0 (void)
     274  {
     275    return strlen (a0);                   // { dg-warning "-Wstringop-overread" }
     276  }
     277  
     278  int warn_strlen_end (void)
     279  {
     280    const char *s = arr + sizeof arr;
     281    return strlen (s);                    // { dg-warning "-Wstringop-overread" }
     282  }
     283  
     284  int warn_strlen_malloc0 (void)
     285  {
     286    char *s = malloc (0);
     287    sink (s);
     288    return strlen (s);                    // { dg-warning "-Wstringop-overread" }
     289  }
     290  
     291  
     292  int nowarn_strnlen (void)
     293  {
     294    return strnlen (unterm, unterm_size);
     295  }
     296  
     297  int warn_strnlen (void)
     298  {
     299    return strnlen (unterm, unterm_size + 1);   // { dg-warning "-Wstringop-overread" }
     300  }
     301  
     302  int warn_strnlen_end (void)
     303  {
     304    const char *s = arr + sizeof arr;
     305    return strnlen (s, 2);                // { dg-warning "-Wstringop-overread" }
     306  }
     307  
     308  
     309  int warn_strcmp_1 (const char *s)
     310  {
     311    return strcmp (unterm, s);            // { dg-warning "-Wstringop-overread" }
     312  }
     313  
     314  int warn_strcmp_2 (const char *s)
     315  {
     316    return strcmp (s, unterm);            // { dg-warning "-Wstringop-overread" }
     317  }
     318  
     319  int warn_strcmp_2_end (const char *s)
     320  {
     321    const char *t = arr + sizeof arr;
     322    return strcmp (s, t);                 // { dg-warning "-Wstringop-overread" }
     323  }
     324  
     325  
     326  int nowarn_strncmp_1 (const char *s2)
     327  {
     328    const char *s1 = unterm;
     329    return strncmp (s1, s2, unterm_size);
     330  }
     331  
     332  int warn_strncmp_1 (const char *s2)
     333  {
     334    const char *s1 = unterm;
     335    return strncmp (s1, s2, unterm_size + 1);  // { dg-warning "-Wstringop-overread" }
     336  }
     337  
     338  int nowarn_strncmp_2 (const char *s1)
     339  {
     340    const char *s2 = unterm;
     341    return strncmp (s1, s2, unterm_size);
     342  }
     343  
     344  int warn_strncmp_2 (const char *s1)
     345  {
     346    const char *s2 = unterm;
     347    return strncmp (s1, s2, unterm_size + 1);  // { dg-warning "-Wstringop-overread" }
     348  }
     349  
     350  int warn_strncmp_2_end (const char *s1)
     351  {
     352    const char *s2 = arr + sizeof arr;;
     353    return strncmp (s1, s2, sizeof arr);  // { dg-warning "-Wstringop-overread" }
     354  }
     355  
     356  
     357  int nowarn_strncmp_1_s2 (void)
     358  {
     359    /* Since the read is also bounded by the length of the S2 literal
     360       and so safe, expect no warning.  */
     361    const char *s = unterm;
     362    return strncmp (s, S2, unterm_size + 1);   // { dg-bogus "-Wstringop-overread" "pr101778" { xfail *-*-* } }
     363  }
     364  
     365  int warn_strncmp_2_s2 (void)
     366  {
     367    /* Same as above.  */
     368    const char *t = unterm;
     369    return strncmp (S2, t, unterm_size + 1);   // { dg-bogus "-Wstringop-overread" "pr101778" { xfail *-*-* } }
     370  }
     371  
     372  
     373  int warn_strncmp_1_s9 (void)
     374  {
     375    /* Since both the bound and the length of the S9 literal are greater
     376       than the size of UNNTERM the call reads past the end of the array.
     377       Expect a warning.  */
     378    const char *s1 = unterm;
     379    return strncmp (s1, S9, unterm_size + 1);  // { dg-warning "-Wstringop-overread" }
     380  }
     381  
     382  int warn_strncmp_2_s9 (void)
     383  {
     384    /* Same as above.  */
     385    const char *s2 = unterm;
     386    return strncmp (S9, s2, unterm_size + 1);  // { dg-warning "-Wstringop-overread" }
     387  }
     388  
     389  
     390  const char* warn_strchr (int x)
     391  {
     392    return strchr (unterm, x);            // { dg-warning "-Wstringop-overread" }
     393  }
     394  
     395  const char* warn_strchr_end (int x)
     396  {
     397    const char *s = arr + sizeof arr;
     398    return strchr (s, x);                 // { dg-warning "-Wstringop-overread" }
     399  }
     400  
     401  
     402  const char* warn_strrchr (int x)
     403  {
     404    return strrchr (unterm, x);           // { dg-warning "-Wstringop-overread" }
     405  }
     406  
     407  const char* warn_strrchr_end (int x)
     408  {
     409    const char *s = arr + sizeof arr;
     410    return strrchr (s, x);                // { dg-warning "-Wstringop-overread" }
     411  }
     412  
     413  
     414  char* warn_strdup (void)
     415  {
     416    return strdup (unterm);               // { dg-warning "-Wstringop-overread" }
     417  }
     418  
     419  char* warn_strdup_end (void)
     420  {
     421    const char *s = arr + sizeof arr;
     422    return strdup (s);                    // { dg-warning "-Wstringop-overread" }
     423  }
     424  
     425  
     426  char* nowarn_strndup (void)
     427  {
     428    return strndup (unterm, unterm_size);
     429  }
     430  
     431  char* warn_strndup (void)
     432  {
     433    return strndup (unterm, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
     434  }
     435  
     436  char* warn_strndup_end (void)
     437  {
     438    const char *s = arr + sizeof arr;
     439    return strndup (s, sizeof arr);       // { dg-warning "-Wstringop-overread" }
     440  }
     441  
     442  
     443  const char* warn_strpbrk_1 (const char *s2)
     444  {
     445    return strpbrk (unterm, s2);          // { dg-warning "-Wstringop-overread" }
     446  }
     447  
     448  const char* warn_strpbrk_2 (const char *s1)
     449  {
     450    return strpbrk (s1, unterm);          // { dg-warning "-Wstringop-overread" }
     451  }
     452  
     453  
     454  size_t warn_strspn_1 (const char *s2)
     455  {
     456    return strspn (unterm, s2);           // { dg-warning "-Wstringop-overread" }
     457  }
     458  
     459  size_t warn_strspn_1_end (const char *s2)
     460  {
     461    const char *s1 = arr + sizeof arr;
     462    return strspn (s1, s2);               // { dg-warning "-Wstringop-overread" }
     463  }
     464  
     465  size_t warn_strspn_2 (const char *s1)
     466  {
     467    return strspn (s1, unterm);           // { dg-warning "-Wstringop-overread" }
     468  }
     469  
     470  size_t warn_strspn_2_end (const char *s1)
     471  {
     472    const char *s2 = arr + sizeof arr;
     473    return strspn (s1, s2);               // { dg-warning "-Wstringop-overread" }
     474  }
     475  
     476  
     477  size_t warn_strcspn_1 (const char *s2)
     478  {
     479    return strcspn (unterm, s2);          // { dg-warning "-Wstringop-overread" }
     480  }
     481  
     482  size_t warn_strcspn_1_end (const char *s2)
     483  {
     484    const char *s1 = arr + sizeof arr;
     485    return strcspn (s1, s2);              // { dg-warning "-Wstringop-overread" }
     486  }
     487  
     488  size_t warn_strcspn_2 (const char *s1)
     489  {
     490    return strcspn (s1, unterm);          // { dg-warning "-Wstringop-overread" }
     491  }
     492  
     493  size_t warn_strcspn_2_end (const char *s1)
     494  {
     495    const char *s2 = arr + sizeof arr;
     496    return strcspn (s1, s2);              // { dg-warning "-Wstringop-overread" }
     497  }
     498  
     499  
     500  const char* warn_strstr_1 (const char *s2)
     501  {
     502    return strstr (unterm, s2);           // { dg-warning "-Wstringop-overread" }
     503  }
     504  
     505  const char* warn_strstr_1_end (const char *s2)
     506  {
     507    const char *s1 = arr + sizeof arr;
     508    return strstr (s1, s2);               // { dg-warning "-Wstringop-overread" }
     509  }
     510  
     511  
     512  const char* warn_strstr_2 (const char *s1)
     513  {
     514    return strstr (s1, unterm);           // { dg-warning "-Wstringop-overread" }
     515  }
     516  
     517  const char* warn_strstr_2_end (const char *s1)
     518  {
     519    const char *s2 = arr + sizeof arr;
     520    return strstr (s1, s2);               // { dg-warning "-Wstringop-overread" }
     521  }
     522  
     523  
     524  void warn_puts (void)
     525  {
     526    puts (unterm);                        // { dg-warning "-Wstringop-overread" }
     527  }
     528  
     529  void warn_puts_end (void)
     530  {
     531    const char *s = arr + sizeof arr;
     532    puts (s);                             // { dg-warning "-Wstringop-overread" }
     533  }
     534  
     535  
     536  void warn_fputs (FILE *f)
     537  {
     538    fputs (unterm, f);                    // { dg-warning "-Wstringop-overread" }
     539  }
     540  
     541  void warn_fputs_end (FILE *f)
     542  {
     543    const char *s = arr + sizeof arr;
     544    fputs (s, f);                         // { dg-warning "-Wstringop-overread" }
     545  }
     546  
     547  
     548  void warn_puts_unlocked (void)
     549  {
     550    puts_unlocked (unterm);               // { dg-warning "-Wstringop-overread" }
     551  }
     552  
     553  void warn_puts_unlocked_end (void)
     554  {
     555    const char *s = arr + sizeof arr;
     556    puts_unlocked (s);                    // { dg-warning "-Wstringop-overread" }
     557  }
     558  
     559  void warn_fputs_unlocked (FILE *f)
     560  {
     561    fputs_unlocked (unterm, f);           // { dg-warning "-Wstringop-overread" }
     562  }
     563  
     564  
     565  const char* warn_gettext (void)
     566  {
     567    return gettext (unterm);              // { dg-warning "-Wstringop-overread" }
     568  }
     569  
     570  const char* warn_gettext_end (void)
     571  {
     572    const char *s = arr + sizeof arr;
     573    return gettext (s);                   // { dg-warning "-Wstringop-overread" }
     574  }