(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wbuiltin-declaration-mismatch-3.c
       1  /* PR c/83656 - missing -Wbuiltin-declaration-mismatch on declaration
       2     without prototype
       3     { dg-do compile }
       4     { dg-options "-Wbuiltin-declaration-mismatch" } */
       5  
       6  typedef __SIZE_TYPE__ size_t;
       7  
       8  /* Built-ins declared without a prototype are not diagnosed by default
       9     (without -Wextra) except when their return type doesn't match.  */
      10  int abort ();       /* { dg-warning "\\\[-Wbuiltin-declaration-mismatch]" } */
      11  
      12  /* Built-ins declared without a prototype are not diagnosed without -Wextra.  */
      13  void exit ();
      14  void* memcpy ();
      15  void* memset ();
      16  
      17  
      18  void test_call_abort (void)
      19  {
      20    /* Verify that a valid call to abort() is not diagnosed.  */
      21    abort ();
      22  
      23    /* Unfortunately, the incompatible declaration above makes GCC "forget"
      24       that abort() is a built-in and so the invalid calls below aren't
      25       diagnosed.  The only saving grace is that the invalid declaration
      26       that differs in the return type is diagnosed by default. */
      27    abort (1);        /* { dg-warning "too many arguments to built-in function .abort. expecting 0" "pr?????" { xfail *-*-* } } */
      28  
      29    abort (1, 2);     /* { dg-warning "too many arguments" "pr?????" { xfail *-*-* } } */
      30  }
      31  
      32  
      33  void test_call_exit (void)
      34  {
      35    /* Verify that valid calls to exit are not diagnosed.  */
      36    exit ('\0');
      37    exit (0);
      38  
      39    /* Also verify calls to the built-in.  */
      40    __builtin_exit ('\0');
      41    __builtin_exit (0);
      42    __builtin_exit (0.0);
      43  
      44    exit ();          /* { dg-warning "too few arguments to built-in function 'exit' expecting 1" } */
      45  
      46    exit (1, 2);      /* { dg-warning "too many arguments" } */
      47  
      48    /* Verify that passing incompatible arguments triggers a warning.  */
      49    exit ("");        /* { dg-warning "\\\[-Wint-conversion]" } */
      50  
      51    struct S { int i; } s = { 0 };
      52    exit (s);         /* { dg-warning "incompatible type for argument 1" } */
      53  }
      54  
      55  
      56  void test_call_memcpy (void *p, const void *q, size_t n)
      57  {
      58    memcpy (p, q, n);
      59  
      60    memcpy ();        /* { dg-warning "too few arguments to built-in function 'memcpy' expecting 3" } */
      61  
      62    memcpy (p);       /* { dg-warning "too few arguments to built-in function 'memcpy' expecting 3" } */
      63  
      64    memcpy (p, q);     /* { dg-warning "too few arguments to built-in function 'memcpy' expecting 3" } */
      65  
      66    memcpy (q, p, n); /* { dg-warning "\\\[-Wdiscarded-qualifiers]" } */
      67  
      68    memcpy (p, n, q); /* { dg-warning "\\\[-Wint-conversion]" } */
      69  
      70    memcpy (p, q, n, 0); /* { dg-warning "too many arguments to built-in function 'memcpy' expecting 3" } */
      71  }
      72  
      73  
      74  typedef void* (memcpy_t)(void*, const void*, size_t);
      75  typedef void* (memset_t)(void*, int, size_t);
      76  
      77  void test_init (void)
      78  {
      79    /* Verify that initialization of a pointer by the address of a built-in
      80       function of a matching type declared without a prototype doesn't
      81       trigger a warning...  */
      82    memset_t *pmemset = memset;
      83  
      84    /* ...but initialization by the address of an incompatible built-in
      85       does even without -Wextra.  */
      86    memcpy_t *pmemcpy = memset;           /* { dg-warning "\\\[-Wincompatible-pointer-types]" } */
      87  }
      88  
      89  
      90  void test_assign (void)
      91  {
      92    /* Same as above but for assignment.  */
      93    memset_t *pmemset;
      94    pmemset = memset;
      95  
      96    memcpy_t *pmemcpy;
      97    pmemcpy = memset;                     /* { dg-warning "\\\[-Wincompatible-pointer-types]" } */
      98  }
      99  
     100  
     101  /* Verify that passing built-ins declared without a prototype to
     102     functions that expect a pointer to a function of a specific type
     103     is diagnosed.  Ditto for return statements.  */
     104  
     105  void take_memcpy (memcpy_t*);
     106  void take_any (int, ...);
     107  
     108  memset_t* pass_args (int i)
     109  {
     110    take_memcpy (memcpy);
     111    take_memcpy (memset);                 /* { dg-warning "\\\[-Wincompatible-pointer-types]" } */
     112  
     113    take_any (0, i ? memcpy : memset);    /* { dg-warning "\\\[-Wincompatible-pointer-types]" } */
     114  
     115    return memcpy;                        /* { dg-warning "\\\[-Wincompatible-pointer-types]" } */
     116  }