From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2209) id 2C9663858D20; Thu, 9 Mar 2023 21:21:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2C9663858D20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1678396892; bh=H1IkxVSZX6Ep5/Bct2LOPtgE0E7qnloh8girf/WdQcY=; h=From:To:Subject:Date:From; b=fUwMl64Zq/m1DL313US5ZCIjY60ylR8xGpQwkLePKlWckOqq3/pMiWBZpzCUw0E1U TRQGMHTDjwAOHUdpyPD691iCBLmUW134yfYlJXKQlFLbgmF6HnhUE0EXv+V+KuBD/G e3Qjgf/IVfGanG5o3huol8Eue/uGH2B8CqBYifTQ= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: David Malcolm To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-6565] testsuite: add various -Wanalyzer-null-dereference false +ve test cases X-Act-Checkin: gcc X-Git-Author: David Malcolm X-Git-Refname: refs/heads/master X-Git-Oldrev: ec4bc86b4399e50a0c848472126dad776772ee1c X-Git-Newrev: 4214bdb1d77ebee04d12f66c831730ed67fedf55 Message-Id: <20230309212132.2C9663858D20@sourceware.org> Date: Thu, 9 Mar 2023 21:21:32 +0000 (GMT) List-Id: https://gcc.gnu.org/g:4214bdb1d77ebee04d12f66c831730ed67fedf55 commit r13-6565-g4214bdb1d77ebee04d12f66c831730ed67fedf55 Author: David Malcolm Date: Thu Mar 9 16:21:02 2023 -0500 testsuite: add various -Wanalyzer-null-dereference false +ve test cases 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. 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 Diff: --- .../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 +++++++++++++++++++++ ...-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c | 98 +++++++++++ ...ull-deref-pr108251-smp_fetch_ssl_fc_has_early.c | 96 ++++++++++ .../null-deref-pr108400-SoftEtherVPN-WebUi.c | 77 ++++++++ 6 files changed, 709 insertions(+) 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; iContexts); 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; iContexts, entry); + Free(entry->Name); + WuFreeContext(entry->Value); + Free(entry); + } + ReleaseList(Expired); + + UnlockList(wu->Contexts); +}