(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
       1  /* Reduced from haproxy's src/ssl_sample.c  */
       2  
       3  /* { dg-additional-options "-O2" } */
       4  
       5  union sample_value {
       6    long long int sint;
       7    /* [...snip...]  */
       8  };
       9  
      10  struct sample_data {
      11   int type;
      12   union sample_value u;
      13  };
      14  
      15  enum {
      16    /* [...snip...]  */
      17   SMP_T_BOOL,
      18    /* [...snip...]  */
      19  };
      20  struct sample {
      21   unsigned int flags;
      22   struct sample_data data;
      23    /* [...snip...]  */
      24   struct session *sess;
      25   struct stream *strm;
      26    /* [...snip...]  */
      27  };
      28  struct arg {
      29    /* [...snip...]  */
      30  };
      31  enum obj_type {
      32   OBJ_TYPE_NONE = 0,
      33    /* [...snip...]  */
      34   OBJ_TYPE_CONN,
      35    /* [...snip...]  */
      36   OBJ_TYPE_CHECK,
      37   OBJ_TYPE_ENTRIES
      38  };
      39  enum {
      40    /* [...snip...]  */
      41   CO_FL_EARLY_SSL_HS = 0x00004000,
      42   CO_FL_EARLY_DATA = 0x00008000,
      43    /* [...snip...]  */
      44   CO_FL_SSL_WAIT_HS = 0x08000000,
      45    /* [...snip...]  */
      46  };
      47  struct connection {
      48   enum obj_type obj_type;
      49   unsigned char err_code;
      50    /* [...snip...]  */
      51   unsigned int flags;
      52    /* [...snip...]  */
      53  };
      54  
      55  static inline enum obj_type obj_type(const enum obj_type *t)
      56  {
      57   if (!t || *t >= OBJ_TYPE_ENTRIES)
      58    return OBJ_TYPE_NONE;
      59   return *t;
      60  }
      61  static inline struct connection *__objt_conn(enum obj_type *t)
      62  {
      63   return ((struct connection *)(((void *)(t)) - ((long)&((struct connection *)0)->obj_type)));
      64  }
      65  static inline struct connection *objt_conn(enum obj_type *t)
      66  {
      67   if (!t || *t != OBJ_TYPE_CONN)
      68     return ((void *)0);
      69   return __objt_conn(t);
      70  }
      71  struct session {
      72    /* [...snip...]  */
      73   enum obj_type *origin;
      74    /* [...snip...]  */
      75  };
      76  typedef struct ssl_st SSL;
      77  SSL *ssl_sock_get_ssl_object(struct connection *conn);
      78  
      79  /*****************************************************************************/
      80  
      81  int
      82  smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const char *kw, void *private)
      83  {
      84   SSL *ssl;
      85   struct connection *conn;
      86  
      87   conn = objt_conn(smp->sess->origin);
      88   ssl = ssl_sock_get_ssl_object(conn);
      89   if (!ssl)
      90    return 0;
      91  
      92   smp->flags = 0;
      93   smp->data.type = SMP_T_BOOL;
      94   smp->data.u.sint = ((conn->flags & CO_FL_EARLY_DATA) && /* { dg-bogus "dereference of NULL" "PR analyzer/108251" { xfail *-*-*} } */
      95       (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_SSL_WAIT_HS))) ? 1 : 0;
      96  
      97   return 1;
      98  }