Successfully regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r13-5654-g598e10cf415f0a.
gcc/testsuite/ChangeLog: * gcc.dg/analyzer/deref-before-check-qemu-qtest_rsp_args.c: New test. Signed-off-by: David Malcolm <dmalc...@redhat.com> --- .../deref-before-check-qemu-qtest_rsp_args.c | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/analyzer/deref-before-check-qemu-qtest_rsp_args.c diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-qemu-qtest_rsp_args.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-qemu-qtest_rsp_args.c new file mode 100644 index 00000000000..2b3ad8c5fb3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-qemu-qtest_rsp_args.c @@ -0,0 +1,73 @@ +/* Reduced from qemu-7.2.0's tests/qtest/libqtest.c. */ + +#define TRUE 1 +#define NULL ((void *)0) + +#define g_assert(expr) \ + do { \ + if (expr) ; else /* { dg-warning "check of '\\*words' for NULL after already dereferencing it" } */ \ + g_assertion_message_expr (#expr); \ +} while (0) + +void g_assertion_message_expr (const char *expr) __attribute__((noreturn)); + +extern int strcmp (const char *__s1, const char *__s2) + __attribute__ ((__nothrow__ , __leaf__, __pure__, __nonnull__ (1, 2))); +typedef char gchar; +typedef int gint; +typedef gint gboolean; +typedef struct _GString GString; + +struct _GString +{ + gchar *str; + /* [...snip...] */ +}; + +extern +gchar* g_string_free (GString *string, + gboolean free_segment); +extern +gchar** g_strsplit (const gchar *string, + const gchar *delimiter, + gint max_tokens); +extern +void g_strfreev (gchar **str_array); + +typedef struct QTestState QTestState; +typedef GString* (*QTestRecvFn)(QTestState *); + +typedef struct QTestClientTransportOps { + /* [...snip...] */ + QTestRecvFn recv_line; +} QTestTransportOps; + +struct QTestState +{ + /* [...snip...] */ + QTestTransportOps ops; + /* [...snip...] */ +}; + +gchar **qtest_rsp_args(QTestState *s, int expected_args) +{ + GString *line; + gchar **words; + /* [...snip...] */ + +redo: + line = s->ops.recv_line(s); + words = g_strsplit(line->str, " ", 0); + g_string_free(line, TRUE); + + if (strcmp(words[0], "IRQ") == 0) { /* { dg-message "pointer '\\*words' is dereferenced here" } */ + /* [...snip...] */ + g_strfreev(words); + goto redo; + } + + g_assert(words[0] != NULL); /* { dg-message "in expansion of macro 'g_assert'" } */ + /* [...snip...] */ + + return words; +} -- 2.26.3