aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-12-04 14:51:32 -0800
committerIan Lance Taylor <iant@golang.org>2020-12-04 14:51:32 -0800
commit945ae3ab27757d3261d99446f96105c5ebe70247 (patch)
treea8a120ef5393206d3bc9d2b5882bac1562824836 /gcc/testsuite/gcc.dg
parentf012991e2db06cc95f7aac8ecb74a1ac5f51f3d2 (diff)
parent918a5b84a2c51dc9d011d39461cc276e6558069d (diff)
downloadgcc-945ae3ab27757d3261d99446f96105c5ebe70247.zip
gcc-945ae3ab27757d3261d99446f96105c5ebe70247.tar.gz
gcc-945ae3ab27757d3261d99446f96105c5ebe70247.tar.bz2
Merge from trunk revision 918a5b84a2c51dc9d011d39461cc276e6558069d
Diffstat (limited to 'gcc/testsuite/gcc.dg')
-rw-r--r--gcc/testsuite/gcc.dg/Wfree-nonheap-object-2.c279
-rw-r--r--gcc/testsuite/gcc.dg/Wfree-nonheap-object-3.c57
-rw-r--r--gcc/testsuite/gcc.dg/Wfree-nonheap-object.c273
-rw-r--r--gcc/testsuite/gcc.dg/Wmismatched-dealloc.c252
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/attr-malloc.c75
-rw-r--r--gcc/testsuite/gcc.dg/free-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/free-2.c18
-rw-r--r--gcc/testsuite/gcc.dg/pr98099.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71816.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr19831-2.c2
14 files changed, 965 insertions, 23 deletions
diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-2.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-2.c
new file mode 100644
index 0000000..2b00d77
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-2.c
@@ -0,0 +1,279 @@
+/* PR ????? - No warning on attempts to access free object
+ Verify that attempting to reallocate unallocated objects referenced
+ either directly or through pointers is diagnosed.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wfree-nonheap-object" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern void free (void*);
+extern void* alloca (size_t);
+extern void* realloc (void*, size_t);
+
+void sink (void*, ...);
+
+extern void* eparr[];
+extern char *eptr;
+
+extern size_t n;
+
+
+void nowarn_realloc (void *p, size_t n)
+{
+ char *q = realloc (p, n);
+ sink (q);
+
+ q = realloc (0, n);
+ sink (q);
+
+ q = realloc (q, n * 2);
+ sink (q);
+}
+
+/* Verify that calling realloc on a pointer to an unknown object minus
+ some nonzero offset isn't diagnosed, but a pointer plus a positive
+ offset is (a positive offset cannot point at the beginning). */
+
+void test_realloc_offset (char *p1, char *p2, char *p3, size_t n, int i)
+{
+ char *q;
+ q = realloc (p1 - 1, n);
+ sink (q);
+
+ q = realloc (p2 + 1, n); // { dg-warning "'realloc' called on pointer 'p2' with nonzero offset 1" }
+ sink (q);
+
+ q = realloc (p3 + i, n);
+ sink (q);
+}
+
+void warn_realloc_extern_arr (void)
+{
+ extern char ecarr[]; // { gg-message "declared here" }
+ char *p = ecarr;
+ char *q = realloc (p, n); // { dg-warning "'realloc' called on unallocated object 'ecarr'" }
+ sink (q);
+}
+
+void warn_realloc_extern_arr_offset (int i)
+{
+ extern char ecarr[];
+ char *p = ecarr + i;
+ char *q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+}
+
+
+void warn_realloc_string (int i)
+{
+ char *p, *q;
+ {
+ p = "123";
+ sink (p);
+ q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+ {
+ p = "234" + 1;
+ sink (p);
+ q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+ {
+ p = "123" + i;
+ sink (p);
+ q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+}
+
+
+void warn_realloc_alloca (int n, int i)
+{
+ char *p, *q;
+ {
+ p = alloca (n);
+ sink (p);
+ q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+ {
+ p = (char*)alloca (n + 1);
+ sink (p);
+ q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+ {
+ p = (char*)alloca (n + 2) + i;
+ sink (p);
+ q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+}
+
+
+void warn_realloc_local_arr (int i)
+{
+ char *q;
+ {
+ char a[4];
+ sink (a);
+ q = realloc (a, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+
+ {
+ char b[5];
+ sink (b);
+ q = realloc (b + 1, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+
+ {
+ char c[6];
+ sink (c);
+ q = realloc (&c[2], n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+
+ {
+ char d[7];
+ sink (d);
+ q = realloc (&d[i], n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+}
+
+void warn_realloc_vla (int n1, int n2, int i)
+{
+ char *q;
+ {
+ char vla[n1];
+ sink (vla);
+ q = realloc (vla, n2); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+
+ {
+ char vlb[n1 + 1];
+ sink (vlb);
+ q = realloc (vlb + 1, n2);// { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+
+ {
+ char vlc[n1 + 2];
+ sink (vlc);
+ q = realloc (&vlc[2], n2);// { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+
+ {
+ char vld[7];
+ sink (vld);
+ q = realloc (&vld[i], n2);// { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+ }
+}
+
+void nowarn_realloc_extern_ptrarr (void)
+{
+ char *q = realloc (*eparr, n);
+ sink (q);
+}
+
+void nowarn_realloc_extern_ptrarr_offset (int i)
+{
+ char *p = eparr[i];
+ char *q = realloc (p, n);
+ sink (q);
+}
+
+
+void warn_realloc_extern_ptrarr (void)
+{
+ char *q = realloc (eparr, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+}
+
+void warn_realloc_extern_ptrarr_offset (int i)
+{
+ void *p = eparr + i;
+ void *q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+}
+
+
+void nowarn_realloc_extern_ptr (void)
+{
+ char *q = realloc (eptr, n);
+ sink (q);
+}
+
+void nowarn_realloc_extern_ptr_offset (int i)
+{
+ char *p = eptr + i;
+ char *q = realloc (p, n);
+ sink (q);
+}
+
+
+void warn_realloc_extern_ptr_pos_offset (int i)
+{
+ if (i <= 0)
+ i = 1;
+
+ char *p = eptr + i;
+ char *q = realloc (p, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+}
+
+
+void nowarn_realloc_parm_offset (char *p, int i)
+{
+ char *q = p + i;
+ q = realloc (q, n);
+ sink (q);
+}
+
+void nowarn_realloc_parm_neg_offset (char *p, int i)
+{
+ if (i >= 0)
+ i = -1;
+
+ char *q = p + i;
+ q = realloc (q, n);
+ sink (q);
+}
+
+void warn_realloc_parm_pos_offset (char *p, int i)
+{
+ if (i <= 0)
+ i = 1;
+
+ char *q = p + i;
+ q = realloc (q, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+}
+
+void nowarn_realloc_deref_parm_pos_offset (void **p, int i)
+{
+ if (i <= 0)
+ i = 1;
+
+ // The offset is from p, not *p.
+ void *q = *(p + i);
+ q = realloc (q, n);
+ sink (q);
+}
+
+void warn_realloc_deref_parm_pos_offset (void **p, int i)
+{
+ if (i <= 0)
+ i = 1;
+
+ // Unlike in the function above the offset is from *p.
+ void *q = *p + i;
+ q = realloc (q, n); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ sink (q);
+}
diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object-3.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-3.c
new file mode 100644
index 0000000..a472b93
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object-3.c
@@ -0,0 +1,57 @@
+/* PR ????? - No warning on attempts to access free object
+ Verify that freeing unallocated objects referenced indirectly through
+ pointers obtained from function calls is diagnosed.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wfree-nonheap-object" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern void free (void*);
+extern char* memchr (const void*, int, size_t);
+extern char* strchr (const char*, int);
+
+void sink (void*, ...);
+
+extern char ecarr[];
+extern void* eparr[];
+
+extern char *eptr;
+
+
+void warn_free_memchr_ecarr (int x, size_t n)
+{
+ char *p = memchr (ecarr, x, n);
+ sink (p);
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+void warn_free_memchr_ecarr_offset (int i, int j, int x, size_t n)
+{
+ char *p = memchr (ecarr + i, x, n);
+ char *q = p + j;
+ sink (p, q);
+ free (q); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+
+void warn_free_memchr_local_arr (int x, size_t n)
+{
+ char a[8];
+ sink (a);
+
+ char *p = memchr (a, x, n);
+ sink (p);
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+void warn_free_memchr_local_arr_offset (int i, int j, int x, size_t n)
+{
+ char a[8];
+ sink (a);
+
+ char *p = memchr (a + i, x, n);
+ char *q = p + j;
+ sink (p, q);
+ free (q); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
diff --git a/gcc/testsuite/gcc.dg/Wfree-nonheap-object.c b/gcc/testsuite/gcc.dg/Wfree-nonheap-object.c
new file mode 100644
index 0000000..bb222cc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wfree-nonheap-object.c
@@ -0,0 +1,273 @@
+/* PR ????? - No warning on attempts to access free object
+ Verify that freeing unallocated objects referenced either directly
+ or through pointers is diagnosed. In most cases this doesn't require
+ optimization.
+ { dg-do compile }
+ { dg-options "-Wall -Wfree-nonheap-object" } */
+
+typedef __INTPTR_TYPE__ intptr_t;
+typedef __SIZE_TYPE__ size_t;
+
+extern void free (void*);
+extern void* malloc (size_t);
+extern void* realloc (void *p, size_t);
+
+void sink (void*, ...);
+
+extern char ecarr[];
+extern void* eparr[];
+
+extern char *eptr;
+
+void* source (void);
+
+void nowarn_free (void *p, void **pp, size_t n, intptr_t iptr)
+{
+ free (p);
+
+ p = 0;
+ free (p);
+
+ p = malloc (n);
+ sink (p);
+ free (p);
+
+ p = malloc (n);
+ sink (p);
+
+ p = realloc (p, n * 2);
+ sink (p);
+ free (p);
+
+ free ((void*)iptr);
+
+ p = source ();
+ free (p);
+
+ p = source ();
+ p = (char*)p - 1;
+ free (p);
+
+ free (*pp);
+}
+
+void warn_free_extern_arr (void)
+{
+ free (ecarr); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+void warn_free_extern_arr_offset (int i)
+{
+ char *p = ecarr + i;
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+
+void warn_free_cstint (void)
+{
+ void *p = (void*)1;
+ sink (p);
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+
+void warn_free_func (void)
+{
+ void *p = warn_free_func;
+ sink (p);
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+
+void warn_free_string (int i)
+{
+ {
+ char *p = "123";
+ sink (p);
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ }
+ {
+ char *p = "234" + 1;
+ sink (p);
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ }
+ {
+ char *p = "345" + i;
+ sink (p);
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ }
+
+ if (i >= 0)
+ {
+ char *p = "456" + i;
+ sink (p);
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ }
+}
+
+void warn_free_local_arr (int i)
+{
+ {
+ char a[4];
+ sink (a);
+ free (a); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ }
+ {
+ char b[5];
+ sink (b);
+
+ char *p = b + 1;
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ }
+ {
+ char c[6];
+ sink (c);
+
+ char *p = c + i;
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ }
+}
+
+
+void warn_free_vla (int n, int i)
+{
+ {
+ int vla[n], *p = vla;
+ sink (p);
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ }
+
+ {
+ int vla[n + 1], *p = vla + 1;
+ sink (p);
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ }
+ {
+ int vla[n + 2], *p = vla + i;
+ sink (p);
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+ }
+}
+
+
+void nowarn_free_extern_ptrarr (void)
+{
+ free (*eparr);
+}
+
+void nowarn_free_extern_ptrarr_offset (int i)
+{
+ char *p = eparr[i];
+ free (p);
+}
+
+
+void warn_free_extern_ptrarr (void)
+{
+ free (eparr); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+void warn_free_extern_ptrarr_offset (int i)
+{
+ void *p = &eparr[i];
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+
+void nowarn_free_local_ptrarr (int i)
+{
+ void* a[4];
+ sink (a);
+ free (a[0]);
+ free (a[1]);
+ free (a[i]);
+}
+
+
+void nowarn_free_extern_ptr (void)
+{
+ free (eptr);
+}
+
+void nowarn_free_extern_ptr_offset (int i)
+{
+ char *p = eptr + i;
+ free (p);
+}
+
+void nowarn_free_parm_offset (char *p, int i)
+{
+ char *q = p + i;
+ free (q);
+}
+
+void nowarn_free_parm_neg_offset (char *p, int i)
+{
+ if (i >= 0)
+ i = -1;
+
+ char *q = p + i;
+ free (q);
+}
+
+struct Members
+{
+ char a[4], *p, *q;
+};
+
+extern struct Members em;
+
+void nowarn_free_member_ptr (struct Members *pm, int i)
+{
+ char *p = em.p;
+ free (p);
+ p = em.q + i;
+ free (p);
+
+ free (pm->q);
+ p = pm->p;
+ free (pm);
+ free (p);
+}
+
+void nowarn_free_struct_cast (intptr_t *p)
+{
+ struct Members *q = (struct Members*)*p;
+ if (q->p == 0)
+ free (q); // { dg-bogus "\\\[-Wfree-nonheap-object" }
+}
+
+
+void warn_free_member_array (void)
+{
+ char *p = em.a;
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+void warn_free_member_array_off (int i)
+{
+ char *p = em.a + i;
+ free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+
+// Range information requires optimization.
+#pragma GCC optimize "1"
+
+void warn_free_extern_ptr_pos_offset (int i)
+{
+ if (i <= 0)
+ i = 1;
+
+ char *q = eptr + i;
+ free (q); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
+
+void warn_free_parm_pos_offset (char *p, int i)
+{
+ if (i <= 0)
+ i = 1;
+
+ char *q = p + i;
+ free (q); // { dg-warning "\\\[-Wfree-nonheap-object" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wmismatched-dealloc.c b/gcc/testsuite/gcc.dg/Wmismatched-dealloc.c
new file mode 100644
index 0000000..7c5d6ac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmismatched-dealloc.c
@@ -0,0 +1,252 @@
+/* PR middle-end/94527 - Add an attribute that marks a function as freeing
+ an object
+ Verify that attribute malloc with one or two arguments has the expected
+ effect on diagnostics.
+ { dg-options "-Wall -ftrack-macro-expansion=0" } */
+
+#define A(...) __attribute__ ((malloc (__VA_ARGS__)))
+
+typedef struct FILE FILE;
+typedef __SIZE_TYPE__ size_t;
+
+void free (void*);
+void* malloc (size_t);
+void* realloc (void*, size_t);
+
+int fclose (FILE*);
+FILE* freopen (const char*, const char*, FILE*);
+int pclose (FILE*);
+
+A (fclose) A (freopen, 3)
+ FILE* fdopen (int);
+A (fclose) A (freopen, 3)
+ FILE* fopen (const char*, const char*);
+A (fclose) A (freopen, 3)
+ FILE* fmemopen(void *, size_t, const char *);
+A (fclose) A (freopen, 3)
+ FILE* freopen (const char*, const char*, FILE*);
+A (pclose) A (freopen, 3)
+ FILE* popen (const char*, const char*);
+A (fclose) A (freopen, 3)
+ FILE* tmpfile (void);
+
+void sink (FILE*);
+
+
+ void release (void*);
+A (release) FILE* acquire (void);
+
+void nowarn_fdopen (void)
+{
+ {
+ FILE *q = fdopen (0);
+ if (!q)
+ return;
+
+ fclose (q);
+ }
+
+ {
+ FILE *q = fdopen (0);
+ if (!q)
+ return;
+
+ q = freopen ("1", "r", q);
+ fclose (q);
+ }
+
+ {
+ FILE *q = fdopen (0);
+ if (!q)
+ return;
+
+ sink (q);
+ }
+}
+
+
+void warn_fdopen (void)
+{
+ {
+ FILE *q = fdopen (0); // { dg-message "returned from a call to 'fdopen'" "note" }
+ sink (q);
+ release (q); // { dg-warning "'release' called on pointer returned from a mismatched allocation function" }
+ }
+ {
+ FILE *q = fdopen (0); // { dg-message "returned from a call to 'fdopen'" "note" }
+ sink (q);
+ free (q); // { dg-warning "'free' called on pointer returned from a mismatched allocation function" }
+ }
+
+ {
+ FILE *q = fdopen (0); // { dg-message "returned from a call to 'fdopen'" "note" }
+ sink (q);
+ q = realloc (q, 7); // { dg-warning "'realloc' called on pointer returned from a mismatched allocation function" }
+ sink (q);
+ }
+}
+
+
+void nowarn_fopen (void)
+{
+ {
+ FILE *q = fopen ("1", "r");
+ sink (q);
+ fclose (q);
+ }
+
+ {
+ FILE *q = fopen ("2", "r");
+ sink (q);
+ q = freopen ("3", "r", q);
+ sink (q);
+ fclose (q);
+ }
+
+ {
+ FILE *q = fopen ("4", "r");
+ sink (q);
+ }
+}
+
+
+void warn_fopen (void)
+{
+ {
+ FILE *q = fopen ("1", "r");
+ sink (q);
+ release (q); // { dg-warning "'release' called on pointer returned from a mismatched allocation function" }
+ }
+ {
+ FILE *q = fdopen (0);
+ sink (q);
+ free (q); // { dg-warning "'free' called on pointer returned from a mismatched allocation function" }
+ }
+
+ {
+ FILE *q = fdopen (0);
+ sink (q);
+ q = realloc (q, 7); // { dg-warning "'realloc' called on pointer returned from a mismatched allocation function" }
+ sink (q);
+ }
+}
+
+
+void test_popen (void)
+{
+ {
+ FILE *p = popen ("1", "r");
+ sink (p);
+ pclose (p);
+ }
+
+ {
+ FILE *p;
+ p = popen ("2", "r"); // { dg-message "returned from a call to 'popen'" "note" }
+ sink (p);
+ fclose (p); // { dg-warning "'fclose' called on pointer returned from a mismatched allocation function" }
+ }
+
+ {
+ /* freopen() can close a stream open by popen() but pclose() can't
+ close the stream returned from freopen(). */
+ FILE *p = popen ("2", "r");
+ sink (p);
+ p = freopen ("3", "r", p); // { dg-message "returned from a call to 'freopen'" "note" }
+ sink (p);
+ pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" }
+ }
+}
+
+
+void test_tmpfile (void)
+{
+ {
+ FILE *p = tmpfile ();
+ sink (p);
+ fclose (p);
+ }
+
+ {
+ FILE *p = tmpfile ();
+ sink (p);
+ p = freopen ("1", "r", p);
+ sink (p);
+ fclose (p);
+ }
+
+ {
+ FILE *p = tmpfile (); // { dg-message "returned from a call to 'tmpfile'" "note" }
+ sink (p);
+ pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" }
+ }
+}
+
+
+void warn_malloc (void)
+{
+ {
+ FILE *p = malloc (100); // { dg-message "returned from a call to 'malloc'" "note" }
+ sink (p);
+ fclose (p); // { dg-warning "'fclose' called on pointer returned from a mismatched allocation function" }
+ }
+
+ {
+ FILE *p = malloc (100); // { dg-message "returned from a call to 'malloc'" "note" }
+ sink (p);
+ p = freopen ("1", "r", p);// { dg-warning "'freopen' called on pointer returned from a mismatched allocation function" }
+ }
+
+ {
+ FILE *p = malloc (100); // { dg-message "returned from a call to 'malloc'" "note" }
+ sink (p);
+ pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" }
+ }
+}
+
+
+void test_acquire (void)
+{
+ {
+ FILE *p = acquire ();
+ release (p);
+ }
+
+ {
+ FILE *p = acquire ();
+ sink (p);
+ release (p);
+ }
+
+ {
+ FILE *p = acquire (); // { dg-message "returned from a call to 'acquire'" "note" }
+ sink (p);
+ fclose (p); // { dg-warning "'fclose' called on pointer returned from a mismatched allocation function" }
+ }
+
+ {
+ FILE *p = acquire (); // { dg-message "returned from a call to 'acquire'" "note" }
+ sink (p);
+ pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" }
+ }
+
+ {
+ FILE *p = acquire (); // { dg-message "returned from a call to 'acquire'" "note" }
+ sink (p);
+ p = freopen ("1", "r", p); // { dg-warning "'freopen' called on pointer returned from a mismatched allocation function" }
+ sink (p);
+ }
+
+ {
+ FILE *p = acquire (); // { dg-message "returned from a call to 'acquire'" "note" }
+ sink (p);
+ free (p); // { dg-warning "'free' called on pointer returned from a mismatched allocation function" }
+ }
+
+ {
+ FILE *p = acquire (); // { dg-message "returned from a call to 'acquire'" "note" }
+ sink (p);
+ p = realloc (p, 123); // { dg-warning "'realloc' called on pointer returned from a mismatched allocation function" }
+ sink (p);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
index c5bf1227c..26d8288 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
@@ -609,3 +609,5 @@ int test_49 (int i)
*p = 1; /* { dg-warning "dereference of NULL 'p' \\\[CWE-476\\\]" } */
return x;
}
+
+/* { dg-prune-output "\\\[-Wfree-nonheap-object" } */
diff --git a/gcc/testsuite/gcc.dg/attr-malloc.c b/gcc/testsuite/gcc.dg/attr-malloc.c
new file mode 100644
index 0000000..14f1980
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-malloc.c
@@ -0,0 +1,75 @@
+/* PR middle-end/94527 - Add an attribute that marks a function as freeing
+ an object
+ Verify that attribute malloc with one or two arguments is accepted where
+ intended and rejected where it's invalid.
+ { dg-options "-Wall -ftrack-macro-expansion=0" } */
+
+#define A(...) __attribute__ ((malloc (__VA_ARGS__)))
+
+A (0) void* alloc_zero (int); // { dg-error "'malloc' attribute argument 1 does not name a function" }
+
+A ("") void* alloc_string (int); // { dg-error "'malloc' attribute argument 1 does not name a function" }
+
+int var;
+A (var) void* alloc_var (int); // { dg-error "'malloc' attribute argument 1 does not name a function" }
+
+typedef struct Type { int i; } Type;
+A (Type) void* alloc_type (int); // { dg-error "expected expression|identifier" }
+
+A (unknown) void* alloc_unknown (int); // { dg-error "'unknown' undeclared" }
+
+void fv_ (); // { dg-message "declared here" }
+A (fv_) void* alloc_fv_ (int); // { dg-error "'malloc' attribute argument 1 must take a pointer type as its first argument" }
+
+void fvi (int); // { dg-message "declared here" }
+A (fvi) void* alloc_fvi (int); // { dg-error "'malloc' attribute argument 1 must take a pointer type as its first argument; have 'int'" }
+
+void fvv (void); // { dg-message "declared here" }
+A (fvv) void* alloc_fvv (int); // { dg-error "'malloc' attribute argument 1 must take a pointer type as its first argument; have 'void'" }
+
+void fvi_ (int, ...); // { dg-message "declared here" }
+A (fvi_) void* alloc_fvi_ (int); // { dg-error "'malloc' attribute argument 1 must take a pointer type as its first argument; have 'int'" }
+
+void fvi_vp (Type, void*); // { dg-message "declared here" }
+A (fvi_vp) void* alloc_fvi_vp (int); // { dg-error "'malloc' attribute argument 1 must take a pointer type as its first argument; have 'Type'" }
+
+
+void fpv (void*);
+A (fpv) void* alloc_fpv (int);
+
+void fpv_i (void*, int);
+A (fpv_i) void* alloc_fpv_i (int);
+
+void fpv_pv (void*, void*);
+A (fpv_i) void* alloc_fpv_pv (int);
+
+
+void gpc (char*);
+void hpi (int*);
+A (fpv) A (gpc) A (hpi) Type* alloc_fpv_gpv (int);
+
+
+/* Verify that the attribute can be applied to <stdio.h> functions. */
+typedef struct FILE FILE;
+typedef __SIZE_TYPE__ size_t;
+
+int fclose (FILE*);
+FILE* fdopen (int);
+FILE* fopen (const char*, const char*);
+FILE* freopen (const char*, const char*, FILE*);
+int pclose (FILE*);
+FILE* popen (const char*, const char*);
+FILE* tmpfile (void);
+
+A (fclose) A (freopen, 3) A (pclose)
+ FILE* fdopen (int);
+A (fclose) A (freopen, 3) A (pclose)
+ FILE* fopen (const char*, const char*);
+A (fclose) A (freopen, 3) A (pclose)
+ FILE* fmemopen(void *, size_t, const char *);
+A (fclose) A (freopen, 3) A (pclose)
+ FILE* freopen (const char*, const char*, FILE*);
+A (fclose) A (freopen, 3) A (pclose)
+ FILE* popen (const char*, const char*);
+A (fclose) A (freopen, 3) A (pclose)
+ FILE* tmpfile (void);
diff --git a/gcc/testsuite/gcc.dg/free-1.c b/gcc/testsuite/gcc.dg/free-1.c
index 5496c84..ad49d78 100644
--- a/gcc/testsuite/gcc.dg/free-1.c
+++ b/gcc/testsuite/gcc.dg/free-1.c
@@ -13,14 +13,14 @@ void foo (void)
static char buf4[10], e;
char *q = buf;
free (p);
- free (q); /* { dg-warning "attempt to free a non-heap object" } */
- free (buf2); /* { dg-warning "attempt to free a non-heap object" } */
- free (&c); /* { dg-warning "attempt to free a non-heap object" } */
- free (buf3); /* { dg-warning "attempt to free a non-heap object" } */
- free (&d); /* { dg-warning "attempt to free a non-heap object" } */
- free (buf4); /* { dg-warning "attempt to free a non-heap object" } */
- free (&e); /* { dg-warning "attempt to free a non-heap object" } */
+ free (q); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (buf2); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (&c); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (buf3); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (&d); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (buf4); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (&e); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
free (&r->a);
- free ("abcd"); /* { dg-warning "attempt to free a non-heap object" } */
- free (L"abcd"); /* { dg-warning "attempt to free a non-heap object" } */
+ free ("abcd"); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (L"abcd"); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
}
diff --git a/gcc/testsuite/gcc.dg/free-2.c b/gcc/testsuite/gcc.dg/free-2.c
index eb94651..edbcdc7 100644
--- a/gcc/testsuite/gcc.dg/free-2.c
+++ b/gcc/testsuite/gcc.dg/free-2.c
@@ -13,14 +13,14 @@ void foo (void)
static char buf4[10], e;
char *q = buf;
free (p);
- free (q); /* At -O0 no warning is reported here. */
- free (buf2); /* { dg-warning "attempt to free a non-heap object" } */
- free (&c); /* { dg-warning "attempt to free a non-heap object" } */
- free (buf3); /* { dg-warning "attempt to free a non-heap object" } */
- free (&d); /* { dg-warning "attempt to free a non-heap object" } */
- free (buf4); /* { dg-warning "attempt to free a non-heap object" } */
- free (&e); /* { dg-warning "attempt to free a non-heap object" } */
+ free (q); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (buf2); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (&c); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (buf3); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (&d); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (buf4); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (&e); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
free (&r->a);
- free ("abcd"); /* { dg-warning "attempt to free a non-heap object" } */
- free (L"abcd"); /* { dg-warning "attempt to free a non-heap object" } */
+ free ("abcd"); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
+ free (L"abcd"); /* { dg-warning "\\\[-Wfree-nonheap-object" } */
}
diff --git a/gcc/testsuite/gcc.dg/pr98099.c b/gcc/testsuite/gcc.dg/pr98099.c
index 34909f2..12e52f2 100644
--- a/gcc/testsuite/gcc.dg/pr98099.c
+++ b/gcc/testsuite/gcc.dg/pr98099.c
@@ -1,7 +1,7 @@
/* PR middle-end/98099 */
/* Reported by G. Steinmetz <gscfq@t-online.de> */
-/* { dg-do compile } */
+/* { dg-do compile { target dfp } } */
/* { dg-options "-fsso-struct=big-endian" } */
struct S { _Decimal128 a; };
diff --git a/gcc/testsuite/gcc.dg/torture/pr71816.c b/gcc/testsuite/gcc.dg/torture/pr71816.c
index be37ad9..cc143fa 100644
--- a/gcc/testsuite/gcc.dg/torture/pr71816.c
+++ b/gcc/testsuite/gcc.dg/torture/pr71816.c
@@ -20,3 +20,7 @@ struct ext2_icount_el *insert_icount_el() {
ext2fs_resize_mem(&insert_icount_el_icount_1);
return 0;
}
+
+/* Passing the address of a declared object to realloc triggers
+ -Wfree-nonheap-object unless -flto is used.
+ { dg-prune-output "\\\[-Wfree-nonheap-object" } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c
index 6a03588..e6dd4be 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized --param case-values-threshold=5" } */
int global;
int foo ();
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c
index 464b1fb..b164067 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized --param case-values-threshold=5" } */
int global;
int foo ();
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c
index f43ce7d..f4d06fe 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized --param case-values-threshold=5" } */
int global;
int global1;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19831-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19831-2.c
index 55b4fd0..df4120d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr19831-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr19831-2.c
@@ -5,7 +5,7 @@ void test1(void)
{
int *p = __builtin_malloc (sizeof (int) * 4);
*p++ = 4;
- __builtin_free (p);
+ __builtin_free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
}
/* Undefined. We can't do anything here. */