public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: David Malcolm <dmalcolm@redhat.com>
To: gcc-patches@gcc.gnu.org
Cc: David Malcolm <dmalcolm@redhat.com>
Subject: [pushed] testsuite: add test coverage for PR analyzer/108045
Date: Mon, 13 Mar 2023 15:00:31 -0400	[thread overview]
Message-ID: <20230313190031.3358543-1-dmalcolm@redhat.com> (raw)

PR analyzer/108045 reports a leak false positive from -fanalyzer.

The false +ve as reported seems to have been fixed by
r13-6589-g14f5e56a8a766c, but with -fanalyzer-call-summaries there are
two additional false +ves which aren't fixed by that commit.

This patch adds test coverage for these cases.

Successfully regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-6640-g129664c67b7745.

gcc/testsuite/ChangeLog:
	PR analyzer/108045
	* gcc.dg/analyzer/leak-pr108045-with-call-summaries.c: New test.
	* gcc.dg/analyzer/leak-pr108045-without-call-summaries.c: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
 .../leak-pr108045-with-call-summaries.c       | 106 +++++++++++++++++
 .../leak-pr108045-without-call-summaries.c    | 107 ++++++++++++++++++
 2 files changed, 213 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/leak-pr108045-with-call-summaries.c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/leak-pr108045-without-call-summaries.c

diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-with-call-summaries.c b/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-with-call-summaries.c
new file mode 100644
index 00000000000..d63be06a9bb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-with-call-summaries.c
@@ -0,0 +1,106 @@
+/* { dg-additional-options "-fanalyzer-call-summaries" } */
+
+typedef __SIZE_TYPE__ size_t;
+#define NULL ((void *)0)
+
+/* data structures */
+
+struct screen_s {
+	size_t rows;
+	size_t cols;
+	char **data;
+};
+
+struct context_s {
+	struct screen_s *scr;
+};
+
+/* global context variable */
+
+static struct context_s *ctx;
+
+/* prototypes */
+
+struct screen_s *screen_create(size_t cols, size_t rows);
+void screen_destroy(struct screen_s *scr);
+void resize_screen(size_t cols, size_t rows);
+
+/* functions */
+
+struct screen_s *screen_create(size_t cols, size_t rows)
+{
+	struct screen_s *result = NULL;
+
+	result = __builtin_calloc(1, sizeof(*result));
+	if (!result)
+		return NULL;
+
+	result->cols = cols;
+	result->rows = rows;
+
+	/* make one allocation which will be accessed like a 2D array */
+	result->data = __builtin_calloc(rows, sizeof(result->data) + sizeof(*result->data) * cols);
+	if (!result->data) {
+		__builtin_free(result);
+		return NULL;
+	}
+
+	/* obtain pointer to start of data area */
+	char *ptr = (char *)(result->data + rows);
+
+	/* setup pointers for each row of data to allow 2D array access */
+	for (size_t row = 0; row < rows; row++)
+		result->data[row] = (ptr + row * cols);
+	/* array can now be accessed like data[row][col] */
+
+	return result;
+}
+
+void screen_destroy(struct screen_s *scr)
+{
+	if (!scr)
+		return;
+
+	__builtin_free(scr->data);
+
+	scr->data = NULL;
+	scr->rows = 0;
+	scr->cols = 0;
+
+	__builtin_free(scr);
+}
+
+void resize_screen(size_t cols, size_t rows)
+{
+	/* create a new screen */
+	struct screen_s *new_scr = NULL;
+	new_scr = screen_create(cols, rows); /* { dg-bogus "leak" "PR 108045" { xfail *-*-* } } */
+	if (!new_scr) {
+		return;
+	}
+
+	/* swap the old screen with the new one */
+	struct screen_s *old_scr = ctx->scr;
+	ctx->scr = new_scr;
+
+	/* omitted: copy the old screen contents to the new screen */
+
+	/* free the old screen */
+	screen_destroy(old_scr);
+}
+
+int main(void)
+{
+	ctx = __builtin_calloc(1, sizeof(*ctx));
+	if (!ctx)
+		__builtin_abort();
+
+	ctx->scr = screen_create(80, 25); /* { dg-bogus "leak" "PR 108045" { xfail *-*-* } } */
+	resize_screen(100, 20);
+
+	/* tidy up and quit */
+	screen_destroy(ctx->scr);
+	__builtin_free(ctx);
+	ctx = NULL;
+	return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-without-call-summaries.c b/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-without-call-summaries.c
new file mode 100644
index 00000000000..ae7a7d5c159
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-without-call-summaries.c
@@ -0,0 +1,107 @@
+/* { dg-additional-options "-fno-analyzer-call-summaries" } */
+/* { dg-additional-options "-Wno-analyzer-too-complex" } */
+
+typedef __SIZE_TYPE__ size_t;
+#define NULL ((void *)0)
+
+/* data structures */
+
+struct screen_s {
+	size_t rows;
+	size_t cols;
+	char **data;
+};
+
+struct context_s {
+	struct screen_s *scr;
+};
+
+/* global context variable */
+
+static struct context_s *ctx;
+
+/* prototypes */
+
+struct screen_s *screen_create(size_t cols, size_t rows);
+void screen_destroy(struct screen_s *scr);
+void resize_screen(size_t cols, size_t rows);
+
+/* functions */
+
+struct screen_s *screen_create(size_t cols, size_t rows)
+{
+	struct screen_s *result = NULL;
+
+	result = __builtin_calloc(1, sizeof(*result));
+	if (!result)
+		return NULL;
+
+	result->cols = cols;
+	result->rows = rows;
+
+	/* make one allocation which will be accessed like a 2D array */
+	result->data = __builtin_calloc(rows, sizeof(result->data) + sizeof(*result->data) * cols);
+	if (!result->data) {
+		__builtin_free(result);
+		return NULL;
+	}
+
+	/* obtain pointer to start of data area */
+	char *ptr = (char *)(result->data + rows);
+
+	/* setup pointers for each row of data to allow 2D array access */
+	for (size_t row = 0; row < rows; row++)
+		result->data[row] = (ptr + row * cols);
+	/* array can now be accessed like data[row][col] */
+
+	return result;
+}
+
+void screen_destroy(struct screen_s *scr)
+{
+	if (!scr)
+		return;
+
+	__builtin_free(scr->data);
+
+	scr->data = NULL;
+	scr->rows = 0;
+	scr->cols = 0;
+
+	__builtin_free(scr); /* { dg-bogus "leak" } */
+}
+
+void resize_screen(size_t cols, size_t rows)
+{
+	/* create a new screen */
+	struct screen_s *new_scr = NULL;
+	new_scr = screen_create(cols, rows); /* { dg-bogus "leak" } */
+	if (!new_scr) {
+		return;
+	}
+
+	/* swap the old screen with the new one */
+	struct screen_s *old_scr = ctx->scr;
+	ctx->scr = new_scr;
+
+	/* omitted: copy the old screen contents to the new screen */
+
+	/* free the old screen */
+	screen_destroy(old_scr);
+}
+
+int main(void)
+{
+	ctx = __builtin_calloc(1, sizeof(*ctx));
+	if (!ctx)
+		__builtin_abort();
+
+	ctx->scr = screen_create(80, 25); /* { dg-bogus "leak" } */
+	resize_screen(100, 20);
+
+	/* tidy up and quit */
+	screen_destroy(ctx->scr);
+	__builtin_free(ctx);
+	ctx = NULL;
+	return 0;
+}
-- 
2.26.3


                 reply	other threads:[~2023-03-13 19:00 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230313190031.3358543-1-dmalcolm@redhat.com \
    --to=dmalcolm@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).