1  /* { dg-require-effective-target sockets } */
       2  /* { dg-skip-if "" { powerpc*-*-aix* } } */
       3  
       4  #include <sys/socket.h>
       5  #include <sys/un.h>
       6  #include <unistd.h>
       7  #include <errno.h>
       8  #include "analyzer-decls.h"
       9  
      10  int test_accept (int fd, struct sockaddr *addr, socklen_t *addrlen)
      11  {
      12    return accept (fd, addr, addrlen);
      13  }
      14  
      15  void test_accept_leak_no_lhs (int fd, struct sockaddr *addr, socklen_t *addrlen)
      16  {
      17    accept (fd, addr, addrlen); /* { dg-warning "leak of file descriptor" } */
      18  }
      19  
      20  void test_accept_leak_with_lhs (int fd, struct sockaddr *addr, socklen_t *addrlen)
      21  {
      22    int newfd = accept (fd, addr, addrlen); /* { dg-message "socket created here" } */
      23  } /* { dg-warning "leak of file descriptor 'newfd'" } */
      24  
      25  int test_accept_null_addr (int fd)
      26  {
      27    return accept (fd, NULL, 0);
      28  }
      29  
      30  int test_accept_uninit_addrlen (int fd)
      31  {
      32    struct sockaddr_storage addr;
      33    socklen_t addr_len;
      34    return accept (fd, (struct sockaddr *)&addr, &addr_len); /* { dg-warning "use of uninitialized value 'addr_len'" } */
      35  }
      36  
      37  int test_accept_writes_to_addr_and_len (int fd)
      38  {
      39    struct sockaddr_storage addr;
      40    socklen_t addr_len = sizeof (addr);
      41    __analyzer_eval (addr_len == sizeof (addr)); /* { dg-warning "TRUE" } */
      42    int newfd = accept (fd, (struct sockaddr *)&addr, &addr_len);
      43    if (newfd == -1)
      44      return newfd;
      45    /* Check that the analyzer considers addr and addr_len to
      46       have been written to.  */
      47    __analyzer_eval (((char *)&addr)[0]); /* { dg-warning "UNKNOWN" } */
      48    __analyzer_eval (addr_len == sizeof (addr)); /* { dg-warning "UNKNOWN" } */
      49    return newfd;
      50  }
      51  
      52  void test_accept_on_new_datagram_socket (void)
      53  {
      54    int fd = socket (AF_UNIX, SOCK_DGRAM, 0);
      55    if (fd == -1)
      56      return;
      57    accept (fd, NULL, NULL); /* { dg-message "'accept' on datagram socket file descriptor 'fd' \\\[-Wanalyzer-fd-type-mismatch\\\]" "warning" } */
      58    /* { dg-message "'accept' expects a stream socket file descriptor but 'fd' is a datagram socket" "final event" { target *-*-* } .-1 } */
      59    close (fd);
      60  }
      61  
      62  int test_accept_on_accept (int fd_a)
      63  {
      64    int fd_b = accept (fd_a, NULL, 0);
      65    if (fd_b == -1)
      66      return -1;
      67  
      68    int fd_c = accept (fd_b, NULL, 0);  /* { dg-warning "'accept' on file descriptor 'fd_b' in wrong phase \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
      69    /* { dg-message "'accept' expects a listening stream socket file descriptor but 'fd_b' is connected" "final event" { target *-*-* } .-1 } */
      70  
      71    return fd_b;
      72  }
      73  
      74  int test_accept_on_constant ()
      75  {
      76    return accept (0, NULL, 0);
      77  }