aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/Wstringop-overflow-36.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/gcc.dg/Wstringop-overflow-36.c')
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-36.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-36.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-36.c
new file mode 100644
index 0000000..3f0874d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-36.c
@@ -0,0 +1,24 @@
+/* Verify that casts between pointers and integers don't trigger false
+ positives. Test derived from Glibc's _dl_allocate_tls_storage() in
+ dl-tls.c.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds" } */
+
+typedef __SIZE_TYPE__ size_t;
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+size_t a;
+size_t s;
+
+void* _dl_allocate_tls_storage (void)
+{
+ void *p = __builtin_malloc (s + a + sizeof (void *));
+
+ char *q = (char *)(__builtin_constant_p (a) && (((a - 1) & a) == 0)
+ ? ((((uintptr_t)p) + a - 1) & ~(a - 1))
+ : (((((uintptr_t)p) + (a - 1)) / a) * a));
+
+ char *r = q + s - sizeof (int[4]);
+ __builtin_memset (r, '\0', sizeof (int[4]));
+ return r;
+}