public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [pushed] testsuite: add various -Wanalyzer-null-dereference false +ve test cases
@ 2023-03-09 21:23 David Malcolm
  0 siblings, 0 replies; only message in thread
From: David Malcolm @ 2023-03-09 21:23 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

There are various -Wanalyzer-null-dereference false +ves in bugzilla
that I've been attempting to fix.  Unfortunately I haven't made much
progress, but it seems worth at least capturing the reduced
reproducers as test cases, to make it easier to spot changes in
behavior.

Successfully regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-6565-g4214bdb1d77ebe.

gcc/testsuite/ChangeLog:
	PR analyzer/102671
	PR analyzer/105755
	PR analyzer/108251
	PR analyzer/108400
	* gcc.dg/analyzer/null-deref-pr102671-1.c: New test, reduced
	from Emacs.
	* gcc.dg/analyzer/null-deref-pr102671-2.c: Likewise.
	* gcc.dg/analyzer/null-deref-pr105755.c: Likewise.
	* gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c:
	New test, reduced from haproxy's src/ssl_sample.c.
	* gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c:
	Likewise.
	* gcc.dg/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c: New
	test, reduced from SoftEtherVPN's src/Cedar/WebUI.c.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
 .../gcc.dg/analyzer/null-deref-pr102671-1.c   | 167 +++++++++++++++
 .../gcc.dg/analyzer/null-deref-pr102671-2.c   |  78 +++++++
 .../gcc.dg/analyzer/null-deref-pr105755.c     | 193 ++++++++++++++++++
 ...f-pr108251-smp_fetch_ssl_fc_has_early-O2.c |  98 +++++++++
 ...eref-pr108251-smp_fetch_ssl_fc_has_early.c |  96 +++++++++
 .../null-deref-pr108400-SoftEtherVPN-WebUi.c  |  77 +++++++
 6 files changed, 709 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-1.c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-2.c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr105755.c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c

diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-1.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-1.c
new file mode 100644
index 00000000000..12a0a48d658
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-1.c
@@ -0,0 +1,167 @@
+/* { dg-additional-options "-O2 -Wno-shift-count-overflow" } */
+
+struct lisp;
+union vectorlike_header { long size; };
+struct Lisp_Symbol { void *unused; };
+extern struct Lisp_Symbol lispsym[];
+
+static _Bool
+TAGGEDP (struct lisp *a, unsigned tag)
+{
+  return ! (((unsigned) (long) a - tag) & 7);
+}
+
+static _Bool
+VECTORLIKEP (struct lisp *x)
+{
+  return TAGGEDP (x, 5);
+}
+
+static _Bool
+PSEUDOVECTOR_TYPEP (union vectorlike_header const *a, int code)
+{
+  long PSEUDOVECTOR_FLAG = 1L << 62;
+  long PVEC_TYPE_MASK = 0x3fL << 24;
+  return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
+	  == (PSEUDOVECTOR_FLAG | (code << 24)));
+}
+
+static _Bool
+PSEUDOVECTORP (struct lisp *a, int code)
+{
+  if (! VECTORLIKEP (a))
+    return 0;
+  else
+    return PSEUDOVECTOR_TYPEP ((union vectorlike_header *) ((char *) a - 5),
+			       code);
+}
+
+static struct lisp *
+builtin_lisp_symbol (int index)
+{
+  return (struct lisp *) (index * sizeof *lispsym);
+}
+
+static _Bool
+NILP (struct lisp *x)
+{
+  return x == builtin_lisp_symbol (0);
+}
+
+
+void wrong_type_argument (struct lisp *, struct lisp *);
+
+static void
+CHECK_TYPE (int ok, struct lisp *predicate, struct lisp *x)
+{
+  if (!ok)
+    wrong_type_argument (predicate, x);
+}
+
+
+struct buffer
+{
+  union vectorlike_header header;
+  struct buffer *base_buffer;
+  int window_count;
+};
+
+static _Bool
+BUFFERP (struct lisp *a)
+{
+  return PSEUDOVECTORP (a, 12);
+}
+
+static struct buffer *
+XBUFFER (struct lisp *a)
+{
+  return (struct buffer *) ((char *) a - 5);
+}
+
+
+struct window
+{
+  union vectorlike_header header;
+  struct lisp *next;
+  struct lisp *contents;
+};
+
+static _Bool
+WINDOWP (struct lisp *a)
+{
+  return PSEUDOVECTORP (a, 12);
+}
+
+static void
+CHECK_WINDOW (struct lisp *x)
+{
+  CHECK_TYPE (WINDOWP (x), builtin_lisp_symbol (1360), x);
+}
+
+static struct window *
+XWINDOW (struct lisp *a)
+{
+  return (struct window *) ((char *) a - 5);
+}
+
+static void
+wset_combination (struct window *w, _Bool horflag, struct lisp *val)
+{
+  w->contents = val;
+}
+
+extern struct lisp *selected_window;
+
+struct window *
+decode_live_window (register struct lisp *window)
+{
+  if (NILP (window))
+    return XWINDOW (selected_window);
+  CHECK_TYPE (WINDOWP (window) && BUFFERP (XWINDOW (window)->contents),
+	      builtin_lisp_symbol (1351), window);
+  return XWINDOW (window);
+}
+
+struct window *
+decode_any_window (register struct lisp *window)
+{
+  struct window *w;
+  if (NILP (window))
+    return XWINDOW (selected_window);
+  CHECK_WINDOW (window);
+  w = XWINDOW (window);
+  return w;
+}
+
+static void
+adjust_window_count (struct window *w, int arg)
+{
+  if (BUFFERP (w->contents))
+    {
+      struct buffer *b = XBUFFER (w->contents);
+      if (b->base_buffer)
+	b = b->base_buffer;
+      b->window_count += arg;
+    }
+}
+
+void
+wset_buffer (struct window *w, struct lisp *val)
+{
+  adjust_window_count (w, -1);
+  w->contents = val;
+  adjust_window_count (w, 1);
+}
+
+void
+delete_all_child_windows (struct lisp *window)
+{
+  struct window *w = XWINDOW (window);
+  if (!NILP (w->next))
+    delete_all_child_windows (w->next);
+  if (WINDOWP (w->contents))
+    {
+      delete_all_child_windows (w->contents);
+      wset_combination (w, 0, builtin_lisp_symbol (0));
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-2.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-2.c
new file mode 100644
index 00000000000..5108182a6c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-2.c
@@ -0,0 +1,78 @@
+/* { dg-additional-options "-O2 -Wno-shift-count-overflow" } */
+
+struct lisp;
+union vectorlike_header { long size; };
+struct Lisp_Symbol { void *unused; };
+extern struct Lisp_Symbol lispsym[];
+struct Lisp_Cons { struct lisp *cdr; };
+
+static struct Lisp_Cons *
+XCONS (struct lisp *a)
+{
+  return (struct Lisp_Cons *) ((char *) a - 3);
+}
+
+static struct lisp *
+XCDR (struct lisp *c)
+{
+  return XCONS (c)->cdr;
+}
+
+static _Bool
+TAGGEDP (struct lisp *a, unsigned tag)
+{
+  return ! (((unsigned) (long) a - tag) & 7);
+}
+
+static _Bool
+VECTORLIKEP (struct lisp *x)
+{
+  return TAGGEDP (x, 5);
+}
+
+static _Bool
+PSEUDOVECTOR_TYPEP (union vectorlike_header const *a, int code)
+{
+  long PSEUDOVECTOR_FLAG = 1L << 62;
+  long PVEC_TYPE_MASK = 0x3fL << 24;
+  return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) /* { dg-bogus "dereference of NULL 'time'" "PR analyzer/107526" { xfail *-*-* } } */
+	  == (PSEUDOVECTOR_FLAG | (code << 24)));
+}
+
+static _Bool
+PSEUDOVECTORP (struct lisp *a, int code)
+{
+  if (! VECTORLIKEP (a))
+    return 0;
+  else
+    return PSEUDOVECTOR_TYPEP ((union vectorlike_header *) ((char *) a - 5),
+			       code);
+}
+
+static _Bool
+FIXNUMP (struct lisp *x)
+{
+  return ! (((unsigned) (long) x - 2) & 3);
+}
+
+static _Bool
+BIGNUMP (struct lisp *x)
+{
+  return PSEUDOVECTORP (x, 2);
+}
+
+void some_function ();
+
+static void
+decode_time_components (struct lisp *low)
+{
+  if (BIGNUMP (low))
+    some_function ();
+}
+
+_Bool
+Ftime_convert (struct lisp *time)
+{
+  decode_time_components (time ? XCDR (time) : time);
+  return BIGNUMP (time);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr105755.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr105755.c
new file mode 100644
index 00000000000..f6bf3830908
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr105755.c
@@ -0,0 +1,193 @@
+/* { dg-additional-options "-Wno-analyzer-too-complex -O2" } */
+
+typedef long int ptrdiff_t;
+typedef long int EMACS_INT;
+typedef long int intmax_t;
+
+enum Lisp_Type
+  {
+    Lisp_Symbol = 0,
+    Lisp_Vectorlike = 5,
+  };
+typedef struct Lisp_X *Lisp_Object;
+
+static inline EMACS_INT
+XLI (Lisp_Object o)
+{
+  return (EMACS_INT) o;
+}
+
+static inline void *
+XLP (Lisp_Object o)
+{
+  return (void *) o;
+}
+
+struct Lisp_Symbol
+{
+  Lisp_Object name;
+  Lisp_Object value;
+};
+extern struct Lisp_Symbol lispsym[1455];
+
+union vectorlike_header
+  {
+    ptrdiff_t size;
+  };
+static inline _Bool
+TAGGEDP (Lisp_Object a, enum Lisp_Type tag)
+{
+  return (! (((unsigned) XLI (a) - (unsigned) (tag)) & 7));
+}
+
+struct Lisp_Symbol_With_Pos
+{
+  union vectorlike_header header;
+  Lisp_Object sym;
+  Lisp_Object pos;
+};
+
+static inline _Bool
+PSEUDOVECTORP (Lisp_Object a, int code)
+{
+  return (TAGGEDP (a, Lisp_Vectorlike)
+	  && ((((union vectorlike_header *)
+		((char *) XLP ((a)) - Lisp_Vectorlike))->size
+	       & 0x400000003f000000)
+	      == (0x4000000000000000 | (code << 24))));
+}
+
+static inline _Bool
+BARE_SYMBOL_P (Lisp_Object x)
+{
+  return TAGGEDP (x, Lisp_Symbol);
+}
+
+static inline _Bool
+SYMBOL_WITH_POS_P (Lisp_Object x)
+{
+  return PSEUDOVECTORP (x, 6);
+}
+
+static inline struct Lisp_Symbol_With_Pos *
+XSYMBOL_WITH_POS (Lisp_Object a)
+{
+  return (struct Lisp_Symbol_With_Pos *) ((char *) XLP (a) - Lisp_Vectorlike);
+}
+
+static inline Lisp_Object
+make_lisp_symbol (struct Lisp_Symbol *sym)
+{
+  return (Lisp_Object) ((char *) sym - (char *) lispsym);
+}
+
+static inline Lisp_Object
+builtin_lisp_symbol (int index)
+{
+  return make_lisp_symbol (&lispsym[index]);
+}
+
+static inline _Bool
+BASE_EQ (Lisp_Object x, Lisp_Object y)
+{
+  return XLI (x) == XLI (y);
+}
+
+extern _Bool symbols_with_pos_enabled;
+
+static inline _Bool
+EQ (Lisp_Object x, Lisp_Object y)
+{
+  return (XLI (x) == XLI (y)
+	  || (symbols_with_pos_enabled
+	      && (SYMBOL_WITH_POS_P (x)
+		  ? (BARE_SYMBOL_P (y)
+		     ? XLI (XSYMBOL_WITH_POS(x)->sym) == XLI (y)
+		     : (SYMBOL_WITH_POS_P(y)
+			&& (XLI (XSYMBOL_WITH_POS(x)->sym)
+			    == XLI (XSYMBOL_WITH_POS(y)->sym))))
+		  : (SYMBOL_WITH_POS_P (y) && BARE_SYMBOL_P (x)
+		     && (XLI (x) == XLI ((XSYMBOL_WITH_POS (y))->sym))))));
+}
+
+static inline _Bool
+NILP (Lisp_Object x)
+{
+  return BASE_EQ (x, builtin_lisp_symbol (0));
+}
+
+static inline _Bool
+ASCII_CHAR_P (intmax_t c)
+{
+  return 0 <= c && c < 0x80;
+}
+
+struct Lisp_Char_Table
+  {
+    union vectorlike_header header;
+    Lisp_Object defalt;
+    Lisp_Object parent;
+    Lisp_Object ascii;
+};
+
+extern Lisp_Object char_table_ref (Lisp_Object, int);
+
+static inline _Bool
+CHAR_TABLE_P (Lisp_Object a)
+{
+  return PSEUDOVECTORP (a, 28);
+}
+
+static inline struct Lisp_Char_Table *
+XCHAR_TABLE (Lisp_Object a)
+{
+  return (struct Lisp_Char_Table *) ((char *) XLP (a) - Lisp_Vectorlike);
+}
+
+struct Lisp_Sub_Char_Table
+{
+  union vectorlike_header header;
+  Lisp_Object contents[];
+};
+
+static inline _Bool
+SUB_CHAR_TABLE_P (Lisp_Object a)
+{
+  return PSEUDOVECTORP (a, 29);
+}
+
+static inline struct Lisp_Sub_Char_Table *
+XSUB_CHAR_TABLE (Lisp_Object a)
+{
+  return (struct Lisp_Sub_Char_Table *) ((char *) XLP (a) - Lisp_Vectorlike);
+}
+
+static inline Lisp_Object
+CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx)
+{
+  for (struct Lisp_Char_Table *tbl = XCHAR_TABLE (ct); ;
+       tbl = XCHAR_TABLE (tbl->parent))
+    {
+      Lisp_Object val = (! SUB_CHAR_TABLE_P (tbl->ascii) ? tbl->ascii
+			 : XSUB_CHAR_TABLE (tbl->ascii)->contents[idx]);
+      if (NILP (val))
+	val = tbl->defalt;
+      if (!NILP (val) || NILP (tbl->parent))
+	return val;
+    }
+}
+
+static inline Lisp_Object
+CHAR_TABLE_REF (Lisp_Object ct, int idx)
+{
+  return (ASCII_CHAR_P (idx)
+	  ? CHAR_TABLE_REF_ASCII (ct, idx)
+	  : char_table_ref (ct, idx));
+}
+
+_Bool
+word_boundary_p (Lisp_Object char_script_table, int c1, int c2)
+{
+  return EQ (CHAR_TABLE_REF (char_script_table, c1),
+	     CHAR_TABLE_REF (char_script_table, c2));
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
new file mode 100644
index 00000000000..2a9c715c32c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
@@ -0,0 +1,98 @@
+/* Reduced from haproxy's src/ssl_sample.c  */
+
+/* { dg-additional-options "-O2" } */
+
+union sample_value {
+  long long int sint;
+  /* [...snip...]  */
+};
+
+struct sample_data {
+ int type;
+ union sample_value u;
+};
+
+enum {
+  /* [...snip...]  */
+ SMP_T_BOOL,
+  /* [...snip...]  */
+};
+struct sample {
+ unsigned int flags;
+ struct sample_data data;
+  /* [...snip...]  */
+ struct session *sess;
+ struct stream *strm;
+  /* [...snip...]  */
+};
+struct arg {
+  /* [...snip...]  */
+};
+enum obj_type {
+ OBJ_TYPE_NONE = 0,
+  /* [...snip...]  */
+ OBJ_TYPE_CONN,
+  /* [...snip...]  */
+ OBJ_TYPE_CHECK,
+ OBJ_TYPE_ENTRIES
+};
+enum {
+  /* [...snip...]  */
+ CO_FL_EARLY_SSL_HS = 0x00004000,
+ CO_FL_EARLY_DATA = 0x00008000,
+  /* [...snip...]  */
+ CO_FL_SSL_WAIT_HS = 0x08000000,
+  /* [...snip...]  */
+};
+struct connection {
+ enum obj_type obj_type;
+ unsigned char err_code;
+  /* [...snip...]  */
+ unsigned int flags;
+  /* [...snip...]  */
+};
+
+static inline enum obj_type obj_type(const enum obj_type *t)
+{
+ if (!t || *t >= OBJ_TYPE_ENTRIES)
+  return OBJ_TYPE_NONE;
+ return *t;
+}
+static inline struct connection *__objt_conn(enum obj_type *t)
+{
+ return ((struct connection *)(((void *)(t)) - ((long)&((struct connection *)0)->obj_type)));
+}
+static inline struct connection *objt_conn(enum obj_type *t)
+{
+ if (!t || *t != OBJ_TYPE_CONN)
+   return ((void *)0);
+ return __objt_conn(t);
+}
+struct session {
+  /* [...snip...]  */
+ enum obj_type *origin;
+  /* [...snip...]  */
+};
+typedef struct ssl_st SSL;
+SSL *ssl_sock_get_ssl_object(struct connection *conn);
+
+/*****************************************************************************/
+
+int
+smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+ SSL *ssl;
+ struct connection *conn;
+
+ conn = objt_conn(smp->sess->origin);
+ ssl = ssl_sock_get_ssl_object(conn);
+ if (!ssl)
+  return 0;
+
+ smp->flags = 0;
+ smp->data.type = SMP_T_BOOL;
+ smp->data.u.sint = ((conn->flags & CO_FL_EARLY_DATA) && /* { dg-bogus "dereference of NULL" "PR analyzer/108251" { xfail *-*-*} } */
+     (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_SSL_WAIT_HS))) ? 1 : 0;
+
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c
new file mode 100644
index 00000000000..d83af19788c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c
@@ -0,0 +1,96 @@
+/* Reduced from haproxy's src/ssl_sample.c  */
+
+union sample_value {
+  long long int sint;
+  /* [...snip...]  */
+};
+
+struct sample_data {
+ int type;
+ union sample_value u;
+};
+
+enum {
+  /* [...snip...]  */
+ SMP_T_BOOL,
+  /* [...snip...]  */
+};
+struct sample {
+ unsigned int flags;
+ struct sample_data data;
+  /* [...snip...]  */
+ struct session *sess;
+ struct stream *strm;
+  /* [...snip...]  */
+};
+struct arg {
+  /* [...snip...]  */
+};
+enum obj_type {
+ OBJ_TYPE_NONE = 0,
+  /* [...snip...]  */
+ OBJ_TYPE_CONN,
+  /* [...snip...]  */
+ OBJ_TYPE_CHECK,
+ OBJ_TYPE_ENTRIES
+};
+enum {
+  /* [...snip...]  */
+ CO_FL_EARLY_SSL_HS = 0x00004000,
+ CO_FL_EARLY_DATA = 0x00008000,
+  /* [...snip...]  */
+ CO_FL_SSL_WAIT_HS = 0x08000000,
+  /* [...snip...]  */
+};
+struct connection {
+ enum obj_type obj_type;
+ unsigned char err_code;
+  /* [...snip...]  */
+ unsigned int flags;
+  /* [...snip...]  */
+};
+
+static inline enum obj_type obj_type(const enum obj_type *t)
+{
+ if (!t || *t >= OBJ_TYPE_ENTRIES)
+  return OBJ_TYPE_NONE;
+ return *t;
+}
+static inline struct connection *__objt_conn(enum obj_type *t)
+{
+ return ((struct connection *)(((void *)(t)) - ((long)&((struct connection *)0)->obj_type)));
+}
+static inline struct connection *objt_conn(enum obj_type *t)
+{
+ if (!t || *t != OBJ_TYPE_CONN)
+   return ((void *)0);
+ return __objt_conn(t);
+}
+struct session {
+  /* [...snip...]  */
+ enum obj_type *origin;
+  /* [...snip...]  */
+};
+typedef struct ssl_st SSL;
+SSL *ssl_sock_get_ssl_object(struct connection *conn);
+
+/*****************************************************************************/
+
+int
+smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+ SSL *ssl;
+ struct connection *conn;
+
+ conn = objt_conn(smp->sess->origin);
+ ssl = ssl_sock_get_ssl_object(conn);
+ if (!ssl)
+  return 0;
+
+ smp->flags = 0;
+ smp->data.type = SMP_T_BOOL;
+ smp->data.u.sint = ((conn->flags & CO_FL_EARLY_DATA) && /* { dg-bogus "dereference of NULL 'conn'" "PR analyzer/108251" { xfail *-*-*} } */
+     (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_SSL_WAIT_HS))) ? 1 : 0;
+
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c
new file mode 100644
index 00000000000..1e4613cd1b1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c
@@ -0,0 +1,77 @@
+/* Reduced from SoftEtherVPN's src/Cedar/WebUI.c.   */
+
+#define NULL ((void *)0)
+typedef int (COMPARE)(void *p1, void *p2);
+typedef unsigned int UINT;
+typedef unsigned long int UINT64;
+typedef struct LIST LIST;
+typedef struct STRMAP_ENTRY STRMAP_ENTRY;
+typedef struct WEBUI
+{
+	/* [...snip...] */
+	LIST *Contexts;
+} WEBUI;
+
+typedef struct WU_CONTEXT
+{
+	/* [...snip...] */
+	UINT64 ExpireDate;
+} WU_CONTEXT;
+
+struct LIST
+{
+	/* [...snip...] */
+	UINT num_item, num_reserved;
+	void **p;
+	/* [...snip...] */
+};
+
+#define	LIST_DATA(o, i)		(((o) != NULL) ? ((o)->p[(i)]) : NULL)
+#define	LIST_NUM(o)			(((o) != NULL) ? (o)->num_item : 0)
+
+
+struct STRMAP_ENTRY
+{
+	char *Name;
+	void *Value;
+};
+
+void Free(void *addr);
+void Add(LIST *o, void *p);
+_Bool Delete(LIST *o, void *p);
+void LockList(LIST *o);
+void UnlockList(LIST *o);
+void ReleaseList(LIST *o);
+LIST *NewList(COMPARE *cmp);
+UINT64 Tick64();
+void WuFreeContext(WU_CONTEXT *context);
+
+void WuExpireSessionKey(WEBUI *wu)
+{
+	LIST *Expired = NewList(NULL);
+	UINT i;
+
+	LockList(wu->Contexts);
+
+	for(i=0; i<LIST_NUM(wu->Contexts); i++)
+	{
+		STRMAP_ENTRY *entry = (STRMAP_ENTRY*)LIST_DATA(wu->Contexts, i);
+		WU_CONTEXT *context = (WU_CONTEXT*)entry->Value; /* { dg-bogus "dereference of NULL 'entry'" "PR analyzer/108400" { xfail *-*-* } } */
+		if(context->ExpireDate < Tick64())
+		{
+			Add(Expired, entry);
+		}
+	}
+
+	for(i=0; i<LIST_NUM(Expired); i++)
+	{
+		STRMAP_ENTRY *entry = LIST_DATA(Expired, i);
+		Delete(wu->Contexts, entry);
+		Free(entry->Name);
+		WuFreeContext(entry->Value);
+		Free(entry);
+	}
+	ReleaseList(Expired);
+
+	UnlockList(wu->Contexts);
+}
-- 
2.26.3


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-03-09 21:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-09 21:23 [pushed] testsuite: add various -Wanalyzer-null-dereference false +ve test cases David Malcolm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).