aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2021-10-26 14:34:16 -0600
committerMartin Sebor <msebor@redhat.com>2021-10-26 16:42:16 -0600
commit88b504b7a8c5affb0ffa97990d22af2b199e36ed (patch)
tree1518210385ea1d93a2eb30912565a2391f289dce /gcc/testsuite
parent65f711203d6c2c2d1a4f90fc61cc074f87568827 (diff)
downloadgcc-88b504b7a8c5affb0ffa97990d22af2b199e36ed.zip
gcc-88b504b7a8c5affb0ffa97990d22af2b199e36ed.tar.gz
gcc-88b504b7a8c5affb0ffa97990d22af2b199e36ed.tar.bz2
Detect overflow by atomic functions [PR102453].
Resolves: PR middle-end/102453 - buffer overflow by atomic built-ins not diagnosed gcc/ChangeLog: PR middle-end/102453 * gimple-ssa-warn-access.cc (pass_waccess::check_atomic_builtin): New. (pass_waccess::check_atomic_builtin): Call it. gcc/testsuite/ChangeLog: PR middle-end/102453 * gcc.dg/Warray-bounds-90.c: New test. * gcc.dg/Wstringop-overflow-77.c: New test. * gcc.dg/Wstringop-overflow-78.c: New test. * gcc.dg/Wstringop-overflow-79.c: New test. * gcc.dg/Wstringop-overflow-80.c: New test. * c-c++-common/gomp/atomic-4.c: Avoid an out-of-bounds access.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-90.c147
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-77.c516
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-78.c518
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-79.c70
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-80.c70
6 files changed, 1322 insertions, 1 deletions
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-4.c b/gcc/testsuite/c-c++-common/gomp/atomic-4.c
index 7f27370..5dd18d1 100644
--- a/gcc/testsuite/c-c++-common/gomp/atomic-4.c
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-4.c
@@ -8,7 +8,7 @@ int *bar(void);
void f1(void)
{
#pragma omp atomic
- a[4] += 1;
+ a[3] += 1;
#pragma omp atomic
*p += 1;
#pragma omp atomic
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-90.c b/gcc/testsuite/gcc.dg/Warray-bounds-90.c
new file mode 100644
index 0000000..2e72a3d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-90.c
@@ -0,0 +1,147 @@
+/* PR middle-end/102453 - buffer overflow by atomic built-ins not diagnosed
+ Verify that out-of-bounds accesses by atomic functions are diagnosed.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+#ifndef __cplusplus
+# define bool _Bool
+#endif
+
+#define load __atomic_load
+#define store __atomic_store
+#define add_fetch __atomic_add_fetch
+#define sub_fetch __atomic_sub_fetch
+#define and_fetch __atomic_and_fetch
+#define or_fetch __atomic_or_fetch
+#define xor_fetch __atomic_xor_fetch
+#define nand_fetch __atomic_nand_fetch
+
+typedef __SIZE_TYPE__ size_t;
+
+void sink (void*, ...);
+#define sink(...) sink (0, __VA_ARGS__)
+
+extern _Bool eb;
+extern char ec;
+extern short int esi;
+extern int ei;
+extern long int eli;
+extern long long int elli;
+
+extern const _Bool ecb;
+extern const char ecc;
+extern const short int ecsi;
+extern const int eci;
+extern const long int ecli;
+extern const long long int eclli;
+
+extern _Atomic _Bool eab;
+extern _Atomic char eac;
+extern _Atomic short int easi;
+extern _Atomic int eai;
+extern _Atomic long int eali;
+extern _Atomic long long int ealli;
+
+extern _Atomic const _Bool eacb;
+extern _Atomic const char eacc;
+extern _Atomic const short int eacsi;
+extern _Atomic const int eaci;
+extern _Atomic const long int eacli;
+extern _Atomic const long long int eaclli;
+
+
+void nowarn_atomic_load (void)
+{
+ load (&eacb, &eb, 0);
+ load (&eacc, &ec, 0);
+ load (&eacsi, &esi, 0);
+ load (&eaci, &ei, 0);
+ load (&eacli, &eli, 0);
+ load (&eaclli, &elli, 0);
+}
+
+
+void warn_atomic_load_note (void)
+{
+ int i; // { dg-message "'i'" }
+
+ int *pi = (int*)((char*)&i + 1);
+ load (&eaci, pi, 0); // { dg-warning "-Warray-bounds" }
+ sink (&i);
+
+ pi = (int*)((char*)&i + 2);
+ load (&eaci, pi, 0); // { dg-warning "-Warray-bounds" }
+ sink (&i);
+
+ pi = &i + 1;
+ load (&eaci, pi, 0); // { dg-warning "-Warray-bounds" }
+ sink (&i);
+}
+
+
+void warn_atomic_load (void)
+{
+ bool *pb = &eb + 1;
+ load (&eacb, pb, 0); // { dg-warning "-Warray-bounds" }
+
+ char *pc = &ec + 1;
+ load (&eacc, pc, 0); // { dg-warning "-Warray-bounds" }
+
+ short *psi = (short*)((char*)&esi + 1);
+ load (&eacsi, psi, 0); // { dg-warning "-Warray-bounds" }
+ psi = (short*)((char*)&esi + 2);
+ load (&eacsi, psi, 0); // { dg-warning "-Warray-bounds" }
+
+ int *pi = (int*)((char*)&ei + 1);
+ load (&eaci, pi, 0); // { dg-warning "-Warray-bounds" }
+ pi = (int*)((char*)&ei + 2);
+ load (&eaci, pi, 0); // { dg-warning "-Warray-bounds" }
+ pi = (int*)((char*)&ei + sizeof ei);
+ load (&eaci, pi, 0); // { dg-warning "-Warray-bounds" }
+
+ long *pli = (long*)((char*)&eli + 1);
+ load (&eacli, pli, 0); // { dg-warning "-Warray-bounds" }
+ pli = (long*)((char*)&eli + 1);
+ load (&eacli, pli, 0); // { dg-warning "-Warray-bounds" }
+ pli = &eli + 1;
+ load (&eacli, pli, 0); // { dg-warning "-Warray-bounds" }
+
+ long long *plli = (long long*)((char*)&elli + 1);
+ load (&eaclli, plli, 0); // { dg-warning "-Warray-bounds" }
+ plli = (long long*)((char*)&elli + 1);
+ load (&eacli, plli, 0); // { dg-warning "-Warray-bounds" }
+ plli = &elli + 1;
+ load (&eaclli, plli, 0); // { dg-warning "-Warray-bounds" }
+}
+
+
+void warn_atomic_store (void)
+{
+ const bool *pb = &eb + 1;
+ store (&eab, pb, 0); // { dg-warning "-Warray-bounds" }
+
+ const char *pc = &ec + 1;
+ store (&eac, pc, 0); // { dg-warning "-Warray-bounds" }
+
+ const short *psi = (const short*)((const char*)&ecsi + 1);
+ store (&easi, psi, 0); // { dg-warning "-Warray-bounds" }
+ psi = (const short*)((const char*)&esi + 2);
+ store (&easi, psi, 0); // { dg-warning "-Warray-bounds" }
+
+ const int *pi = (const int*)((const char*)&eci + 1);
+ store (&eai, pi, 0); // { dg-warning "-Warray-bounds" }
+ pi = (const int*)((const char*)&ei + 2);
+ store (&eai, pi, 0); // { dg-warning "-Warray-bounds" }
+ pi = (const int*)((const char*)&ei + sizeof ei);
+ store (&eai, pi, 0); // { dg-warning "-Warray-bounds" }
+
+ const long *pli = (const long*)((const char*)&eli + 1);
+ store (&eali, pli, 0); // { dg-warning "-Warray-bounds" }
+ pli = (const long*)((const char*)&eli + sizeof (eli));
+ store (&eali, pli, 0); // { dg-warning "-Warray-bounds" }
+
+ const long long *plli = (const long long*)((const char*)&elli + 1);
+ store (&ealli, plli, 0); // { dg-warning "-Warray-bounds" }
+ plli = (const long long*)((const char*)&elli + sizeof elli);
+ store (&ealli, plli, 0); // { dg-warning "-Warray-bounds" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-77.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-77.c
new file mode 100644
index 0000000..732f568
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-77.c
@@ -0,0 +1,516 @@
+/* PR middle-end/102453 - buffer overflow by atomic built-ins not diagnosed
+ Verify that out-of-bounds accesses by atomic functions are diagnosed with
+ optimization disabled.
+ { dg-do compile }
+ { dg-options "-O0 -Wall -ftrack-macro-expansion=0" } */
+
+#ifndef __cplusplus
+# define bool _Bool
+#endif
+
+#define add_fetch(p, q) __atomic_add_fetch (p, q, 0)
+#define sub_fetch(p, q) __atomic_sub_fetch (p, q, 0)
+#define and_fetch(p, q) __atomic_and_fetch (p, q, 0)
+#define or_fetch(p, q) __atomic_or_fetch (p, q, 0)
+#define xor_fetch(p, q) __atomic_xor_fetch (p, q, 0)
+#define nand_fetch(p, q) __atomic_nand_fetch (p, q, 0)
+#define exchange(p, q, r) __atomic_exchange (p, q, r, 0)
+#define exchange_n(p, n) __atomic_exchange_n (p, n, 0)
+#define cmpxchg(p, q, r) __atomic_compare_exchange (p, q, r, 0, 0, 0)
+
+typedef __SIZE_TYPE__ size_t;
+
+void sink (void*, ...);
+#define sink(...) sink (0, __VA_ARGS__)
+
+extern _Bool eb;
+extern char ec;
+extern short int esi;
+extern int ei;
+extern long int eli;
+extern long long int elli;
+
+extern const _Bool ecb;
+extern const char ecc;
+extern const short int ecsi;
+extern const int eci;
+extern const long int ecli;
+extern const long long int eclli;
+
+extern _Atomic _Bool eab;
+extern _Atomic char eac;
+extern _Atomic short int easi;
+extern _Atomic int eai;
+extern _Atomic long int eali;
+extern _Atomic long long int ealli;
+
+extern _Atomic const _Bool eacb;
+extern _Atomic const char eacc;
+extern _Atomic const short int eacsi;
+extern _Atomic const int eaci;
+extern _Atomic const long int eacli;
+extern _Atomic const long long int eaclli;
+
+
+void nowarn_atomic_add_fetch (void)
+{
+ add_fetch (&eac, ecc);
+ add_fetch (&easi, esi);
+ add_fetch (&eai, ei);
+ add_fetch (&eali, eli);
+ add_fetch (&ealli, elli);
+}
+
+
+void warn_atomic_add_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ add_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ add_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ add_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ add_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ add_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ add_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ add_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ add_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ add_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ add_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ add_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ add_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+void nowarn_atomic_sub_fetch (void)
+{
+ _Atomic char *pc = &eac;
+ sub_fetch (pc, ecc);
+
+ _Atomic short *psi = &easi;
+ sub_fetch (psi, esi);
+
+ _Atomic int *pi = &eai;
+ sub_fetch (pi, ei);
+
+ _Atomic long *pli = &eali;
+ sub_fetch (pli, eli);
+
+ _Atomic long long *plli = &ealli;
+ sub_fetch (plli, elli);
+}
+
+
+void warn_atomic_sub_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ sub_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ sub_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ sub_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ sub_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ sub_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ sub_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ sub_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ sub_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ sub_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ sub_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ sub_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ sub_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+void nowarn_atomic_and_fetch (void)
+{
+ _Atomic char *pc = &eac;
+ and_fetch (pc, ecc);
+
+ _Atomic short *psi = &easi;
+ and_fetch (psi, esi);
+
+ _Atomic int *pi = &eai;
+ and_fetch (pi, ei);
+
+ _Atomic long *pli = &eali;
+ and_fetch (pli, eli);
+
+ _Atomic long long *plli = &ealli;
+ and_fetch (plli, elli);
+}
+
+
+void warn_atomic_and_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ and_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ and_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ and_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ and_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ and_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ and_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ and_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ and_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ and_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ and_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ and_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ and_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+void nowarn_atomic_or_fetch (void)
+{
+ _Atomic char *pc = &eac;
+ or_fetch (pc, ecc);
+
+ _Atomic short *psi = &easi;
+ or_fetch (psi, esi);
+
+ _Atomic int *pi = &eai;
+ or_fetch (pi, ei);
+
+ _Atomic long *pli = &eali;
+ or_fetch (pli, eli);
+
+ _Atomic long long *plli = &ealli;
+ or_fetch (plli, elli);
+}
+
+
+void warn_atomic_or_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ or_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ or_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ or_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ or_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ or_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ or_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ or_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ or_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ or_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ or_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ or_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ or_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+void nowarn_atomic_xor_fetch (void)
+{
+ _Atomic char *pc = &eac;
+ xor_fetch (pc, ecc);
+
+ _Atomic short *psi = &easi;
+ xor_fetch (psi, esi);
+
+ _Atomic int *pi = &eai;
+ xor_fetch (pi, ei);
+
+ _Atomic long *pli = &eali;
+ xor_fetch (pli, eli);
+
+ _Atomic long long *plli = &ealli;
+ xor_fetch (plli, elli);
+}
+
+
+void warn_atomic_xor_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ xor_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ xor_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 1);
+ xor_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ xor_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ xor_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ xor_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ xor_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ xor_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ xor_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ xor_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&eali + 1);
+ xor_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ xor_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+void nowarn_atomic_nand_fetch (void)
+{
+ _Atomic char *pc = &eac;
+ nand_fetch (pc, ecc);
+
+ _Atomic short *psi = &easi;
+ nand_fetch (psi, esi);
+
+ _Atomic int *pi = &eai;
+ nand_fetch (pi, ei);
+
+ _Atomic long *pli = &eali;
+ nand_fetch (pli, eli);
+
+ _Atomic long long *plli = &ealli;
+ nand_fetch (plli, elli);
+}
+
+
+void warn_atomic_nand_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ nand_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ nand_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 1);
+ nand_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ nand_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ nand_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ nand_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ nand_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ nand_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ nand_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ nand_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&eai + 1);
+ nand_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ nand_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+void nowarn_atomic_exchange (void)
+{
+ char rc;
+ _Atomic char *pc = &eac;
+ exchange (pc, &ecc, &rc);
+
+ short rsi;
+ _Atomic short *psi = &easi;
+ exchange (psi, &esi, &rsi);
+
+ int ri;
+ _Atomic int *pi = &eai;
+ exchange (pi, &ei, &ri);
+
+ long rli;
+ _Atomic long *pli = &eali;
+ exchange (pli, &eli, &rli);
+
+ long long rlli;
+ _Atomic long long *plli = &ealli;
+ exchange (plli, &elli, &rlli);
+
+ sink (&rc, &rsi, &ri, &rli, &rlli);
+}
+
+void warn_atomic_exchange (void)
+{
+ char rc;
+ _Atomic char *pc = &eac + 1;
+ exchange (pc, &ecc, &rc); // { dg-warning "-Wstringop-overflow" }
+
+ short rsi[2];
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ exchange (psi, &ecsi, rsi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ exchange (psi, &ecsi, rsi + 1); // { dg-warning "-Wstringop-overflow" }
+
+ int ri[3];
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ exchange (pi, &eci, ri); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ exchange (pi, &eci, ri + 1); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ exchange (pi, &eci, ri + 2); // { dg-warning "-Wstringop-overflow" }
+
+ long rli[3];
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ exchange (pli, &ecli, rli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ exchange (pli, &ecli, rli + 1); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ exchange (pli, &ecli, rli + 2); // { dg-warning "-Wstringop-overflow" }
+
+ long long rlli[3];
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ exchange (plli, &eclli, rlli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ exchange (plli, &eclli, rlli + 1); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ exchange (plli, &eclli, rlli + 2); // { dg-warning "-Wstringop-overflow" }
+
+ sink (&rc, rsi, ri, rli, rlli);
+}
+
+
+void nowarn_atomic_exchange_n (_Atomic unsigned char *pauc,
+ _Atomic unsigned short *pausi,
+ _Atomic unsigned int *paui,
+ _Atomic unsigned long *pauli,
+ _Atomic unsigned long long *paulli)
+{
+ char rc = exchange_n (&eac, ecc);
+ short rsi = exchange_n (&easi, esi);
+ int ri = exchange_n (&eai, ei);
+ long rli = exchange_n (&eali, eli);
+ long long rlli = exchange_n (&ealli, elli);
+
+ sink (rc, rsi, ri, rli, rlli);
+
+ char ruc = exchange_n (pauc, ecc);
+ short rusi = exchange_n (pausi, esi);
+ int rui = exchange_n (paui, ei);
+ long ruli = exchange_n (pauli, eli);
+ long long rulli = exchange_n (paulli, elli);
+
+ sink (ruc, rusi, rui, ruli, rulli);
+}
+
+
+void warn_atomic_exchange_n (void)
+{
+ _Atomic char *pc = &eac + 1;
+ char rc = exchange_n (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ short rsi[2];
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ rsi[0] = exchange_n (psi, ecsi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ rsi[1] = exchange_n (psi, ecsi); // { dg-warning "-Wstringop-overflow" }
+
+ int ri[3];
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ ri[0] = exchange_n (pi, eci); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ ri[1] = exchange_n (pi, eci); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ ri[2] = exchange_n (pi, eci); // { dg-warning "-Wstringop-overflow" }
+
+ long rli[3];
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ rli[0] = exchange_n (pli, ecli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ rli[1] = exchange_n (pli, ecli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ rli[2] = exchange_n (pli, ecli); // { dg-warning "-Wstringop-overflow" }
+
+ long long rlli[3];
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ rlli[0] = exchange_n (plli, eclli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ rlli[1] = exchange_n (plli, eclli); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ rlli[2] = exchange_n (plli, eclli); // { dg-warning "-Wstringop-overflow" }
+
+ sink (&rc, rsi, ri, rli, rlli);
+}
+
+
+void warn_atomic_compare_exchange (void)
+{
+ _Atomic char *pc = &eac + 1;
+ cmpxchg (pc, &ec, &ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ cmpxchg (psi, &esi, &ecsi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ cmpxchg (psi, &esi, &ecsi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ cmpxchg (pi, &ei, &eci); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ cmpxchg (pi, &ei, &eci); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ cmpxchg (pi, &ei, &eci); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ cmpxchg (pli, &eli, &ecli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ cmpxchg (pli, &eli, &ecli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ cmpxchg (pli, &eli, &ecli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ cmpxchg (plli, &elli, &eclli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ cmpxchg (plli, &elli, &eclli); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ cmpxchg (plli, &elli, &eclli); // { dg-warning "-Wstringop-overflow" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-78.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-78.c
new file mode 100644
index 0000000..a25a418
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-78.c
@@ -0,0 +1,518 @@
+/* PR middle-end/102453 - buffer overflow by atomic built-ins not diagnosed
+ Verify that out-of-bounds accesses by atomic functions are diagnosed with
+ optimization enabled.
+ { dg-do compile }
+ { dg-options "-O3 -Wall -ftrack-macro-expansion=0" } */
+
+#ifndef __cplusplus
+# define bool _Bool
+#endif
+
+#define NOIPA __attribute__ ((noipa))
+
+#define add_fetch(p, q) __atomic_add_fetch (p, q, 0)
+#define sub_fetch(p, q) __atomic_sub_fetch (p, q, 0)
+#define and_fetch(p, q) __atomic_and_fetch (p, q, 0)
+#define or_fetch(p, q) __atomic_or_fetch (p, q, 0)
+#define xor_fetch(p, q) __atomic_xor_fetch (p, q, 0)
+#define nand_fetch(p, q) __atomic_nand_fetch (p, q, 0)
+#define exchange(p, q, r) __atomic_exchange (p, q, r, 0)
+#define exchange_n(p, n) __atomic_exchange_n (p, n, 0)
+#define cmpxchg(p, q, r) __atomic_compare_exchange (p, q, r, __COUNTER__, 0, 0)
+
+typedef __SIZE_TYPE__ size_t;
+
+void sink (void*, ...);
+#define sink(...) sink (0, __VA_ARGS__)
+
+extern _Bool eb;
+extern char ec;
+extern short int esi;
+extern int ei;
+extern long int eli;
+extern long long int elli;
+
+extern const _Bool ecb;
+extern const char ecc;
+extern const short int ecsi;
+extern const int eci;
+extern const long int ecli;
+extern const long long int eclli;
+
+extern _Atomic _Bool eab;
+extern _Atomic char eac;
+extern _Atomic short int easi;
+extern _Atomic int eai;
+extern _Atomic long int eali;
+extern _Atomic long long int ealli;
+
+extern _Atomic const _Bool eacb;
+extern _Atomic const char eacc;
+extern _Atomic const short int eacsi;
+extern _Atomic const int eaci;
+extern _Atomic const long int eacli;
+extern _Atomic const long long int eaclli;
+
+
+NOIPA void nowarn_atomic_add_fetch (void)
+{
+ add_fetch (&eac, ecc);
+ add_fetch (&easi, esi);
+ add_fetch (&eai, ei);
+ add_fetch (&eali, eli);
+ add_fetch (&ealli, elli);
+}
+
+
+NOIPA void warn_atomic_add_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ add_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ add_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ add_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ add_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ add_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ add_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ add_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ add_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ add_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ add_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ add_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ add_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void nowarn_atomic_sub_fetch (void)
+{
+ _Atomic char *pc = &eac;
+ sub_fetch (pc, ecc);
+
+ _Atomic short *psi = &easi;
+ sub_fetch (psi, esi);
+
+ _Atomic int *pi = &eai;
+ sub_fetch (pi, ei);
+
+ _Atomic long *pli = &eali;
+ sub_fetch (pli, eli);
+
+ _Atomic long long *plli = &ealli;
+ sub_fetch (plli, elli);
+}
+
+
+NOIPA void warn_atomic_sub_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ sub_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ sub_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ sub_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ sub_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ sub_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ sub_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ sub_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ sub_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ sub_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ sub_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ sub_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ sub_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void nowarn_atomic_and_fetch (void)
+{
+ _Atomic char *pc = &eac;
+ and_fetch (pc, ecc);
+
+ _Atomic short *psi = &easi;
+ and_fetch (psi, esi);
+
+ _Atomic int *pi = &eai;
+ and_fetch (pi, ei);
+
+ _Atomic long *pli = &eali;
+ and_fetch (pli, eli);
+
+ _Atomic long long *plli = &ealli;
+ and_fetch (plli, elli);
+}
+
+
+NOIPA void warn_atomic_and_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ and_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ and_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ and_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ and_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ and_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ and_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ and_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ and_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ and_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ and_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ and_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ and_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void nowarn_atomic_or_fetch (void)
+{
+ _Atomic char *pc = &eac;
+ or_fetch (pc, ecc);
+
+ _Atomic short *psi = &easi;
+ or_fetch (psi, esi);
+
+ _Atomic int *pi = &eai;
+ or_fetch (pi, ei);
+
+ _Atomic long *pli = &eali;
+ or_fetch (pli, eli);
+
+ _Atomic long long *plli = &ealli;
+ or_fetch (plli, elli);
+}
+
+
+NOIPA void warn_atomic_or_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ or_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ or_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ or_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ or_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ or_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ or_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ or_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ or_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ or_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ or_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ or_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ or_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void nowarn_atomic_xor_fetch (void)
+{
+ _Atomic char *pc = &eac;
+ xor_fetch (pc, ecc);
+
+ _Atomic short *psi = &easi;
+ xor_fetch (psi, esi);
+
+ _Atomic int *pi = &eai;
+ xor_fetch (pi, ei);
+
+ _Atomic long *pli = &eali;
+ xor_fetch (pli, eli);
+
+ _Atomic long long *plli = &ealli;
+ xor_fetch (plli, elli);
+}
+
+
+NOIPA void warn_atomic_xor_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ xor_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ xor_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 1);
+ xor_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ xor_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ xor_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ xor_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ xor_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ xor_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ xor_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ xor_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&eali + 1);
+ xor_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ xor_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void nowarn_atomic_nand_fetch (void)
+{
+ _Atomic char *pc = &eac;
+ nand_fetch (pc, ecc);
+
+ _Atomic short *psi = &easi;
+ nand_fetch (psi, esi);
+
+ _Atomic int *pi = &eai;
+ nand_fetch (pi, ei);
+
+ _Atomic long *pli = &eali;
+ nand_fetch (pli, eli);
+
+ _Atomic long long *plli = &ealli;
+ nand_fetch (plli, elli);
+}
+
+
+NOIPA void warn_atomic_nand_fetch (void)
+{
+ _Atomic char *pc = &eac + 1;
+ nand_fetch (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ nand_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 1);
+ nand_fetch (psi, esi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ nand_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ nand_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ nand_fetch (pi, ei); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ nand_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ nand_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ nand_fetch (pli, eli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ nand_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&eai + 1);
+ nand_fetch (plli, eali); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ nand_fetch (plli, elli); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void nowarn_atomic_exchange (void)
+{
+ char rc;
+ _Atomic char *pc = &eac;
+ exchange (pc, &ecc, &rc);
+
+ short rsi;
+ _Atomic short *psi = &easi;
+ exchange (psi, &esi, &rsi);
+
+ int ri;
+ _Atomic int *pi = &eai;
+ exchange (pi, &ei, &ri);
+
+ long rli;
+ _Atomic long *pli = &eali;
+ exchange (pli, &eli, &rli);
+
+ long long rlli;
+ _Atomic long long *plli = &ealli;
+ exchange (plli, &elli, &rlli);
+
+ sink (&rc, &rsi, &ri, &rli, &rlli);
+}
+
+NOIPA void warn_atomic_exchange (void)
+{
+ char rc;
+ _Atomic char *pc = &eac + 1;
+ exchange (pc, &ecc, &rc); // { dg-warning "-Wstringop-overflow" }
+
+ short rsi[2];
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ exchange (psi, &ecsi, rsi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ exchange (psi, &ecsi, rsi + 1); // { dg-warning "-Wstringop-overflow" }
+
+ int ri[3];
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ exchange (pi, &eci, ri); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ exchange (pi, &eci, ri + 1); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ exchange (pi, &eci, ri + 2); // { dg-warning "-Wstringop-overflow" }
+
+ long rli[3];
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ exchange (pli, &ecli, rli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ exchange (pli, &ecli, rli + 1); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ exchange (pli, &ecli, rli + 2); // { dg-warning "-Wstringop-overflow" }
+
+ long long rlli[3];
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ exchange (plli, &eclli, rlli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ exchange (plli, &eclli, rlli + 1); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ exchange (plli, &eclli, rlli + 2); // { dg-warning "-Wstringop-overflow" }
+
+ sink (&rc, rsi, ri, rli, rlli);
+}
+
+
+NOIPA void nowarn_atomic_exchange_n (_Atomic unsigned char *pauc,
+ _Atomic unsigned short *pausi,
+ _Atomic unsigned int *paui,
+ _Atomic unsigned long *pauli,
+ _Atomic unsigned long long *paulli)
+{
+ char rc = exchange_n (&eac, ecc);
+ short rsi = exchange_n (&easi, esi);
+ int ri = exchange_n (&eai, ei);
+ long rli = exchange_n (&eali, eli);
+ long long rlli = exchange_n (&ealli, elli);
+
+ sink (rc, rsi, ri, rli, rlli);
+
+ char ruc = exchange_n (pauc, ecc);
+ short rusi = exchange_n (pausi, esi);
+ int rui = exchange_n (paui, ei);
+ long ruli = exchange_n (pauli, eli);
+ long long rulli = exchange_n (paulli, elli);
+
+ sink (ruc, rusi, rui, ruli, rulli);
+}
+
+
+NOIPA void warn_atomic_exchange_n (void)
+{
+ _Atomic char *pc = &eac + 1;
+ char rc = exchange_n (pc, ecc); // { dg-warning "-Wstringop-overflow" }
+
+ short rsi[2];
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ rsi[0] = exchange_n (psi, ecsi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ rsi[1] = exchange_n (psi, ecsi); // { dg-warning "-Wstringop-overflow" }
+
+ int ri[3];
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ ri[0] = exchange_n (pi, eci); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ ri[1] = exchange_n (pi, eci); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ ri[2] = exchange_n (pi, eci); // { dg-warning "-Wstringop-overflow" }
+
+ long rli[3];
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ rli[0] = exchange_n (pli, ecli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ rli[1] = exchange_n (pli, ecli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ rli[2] = exchange_n (pli, ecli); // { dg-warning "-Wstringop-overflow" }
+
+ long long rlli[3];
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ rlli[0] = exchange_n (plli, eclli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ rlli[1] = exchange_n (plli, eclli); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ rlli[2] = exchange_n (plli, eclli); // { dg-warning "-Wstringop-overflow" }
+
+ sink (&rc, rsi, ri, rli, rlli);
+}
+
+
+NOIPA void warn_atomic_compare_exchange (void)
+{
+ _Atomic char *pc = &eac + 1;
+ cmpxchg (pc, &ec, &ecc); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic short *psi = (_Atomic short*)((char*)&easi + 1);
+ cmpxchg (psi, &esi, &ecsi); // { dg-warning "-Wstringop-overflow" }
+ psi = (_Atomic short*)((char*)&easi + 2);
+ cmpxchg (psi, &esi, &ecsi); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic int *pi = (_Atomic int*)((char*)&eai + 1);
+ cmpxchg (pi, &ei, &eci); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + 2);
+ cmpxchg (pi, &ei, &eci); // { dg-warning "-Wstringop-overflow" }
+ pi = (_Atomic int*)((char*)&eai + sizeof eai);
+ cmpxchg (pi, &ei, &eci); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long *pli = (_Atomic long*)((char*)&eali + 1);
+ cmpxchg (pli, &eli, &ecli); // { dg-warning "-Wstringop-overflow" }
+ pli = (_Atomic long*)((char*)&eali + 1);
+ cmpxchg (pli, &eli, &ecli); // { dg-warning "-Wstringop-overflow" }
+ pli = &eali + 1;
+ cmpxchg (pli, &eli, &ecli); // { dg-warning "-Wstringop-overflow" }
+
+ _Atomic long long *plli = (_Atomic long long*)((char*)&ealli + 1);
+ cmpxchg (plli, &elli, &eclli); // { dg-warning "-Wstringop-overflow" }
+ plli = (_Atomic long long*)((char*)&ealli + 1);
+ cmpxchg (plli, &elli, &eclli); // { dg-warning "-Wstringop-overflow" }
+ plli = &ealli + 1;
+ cmpxchg (plli, &elli, &eclli); // { dg-warning "-Wstringop-overflow" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-79.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-79.c
new file mode 100644
index 0000000..15eb26f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-79.c
@@ -0,0 +1,70 @@
+/* Verify that a separate note is issued for each offset into the same
+ object after a -Wstringop-overflow. Since all arguments are known
+ the test doesn't need optimization. Wstringop-overflow-79.c verifies
+ they're also issued at -O2.
+ { dg-do compile }
+ { dg-options "-O0 -Wno-array-bounds" } */
+
+extern char a[8]; // dg-message at offset \\\[3, 6] into destination object 'a'" "note 1" }
+ // dg-message at offset \\\[5, 8] into destination object 'a'" "note 2" { target *-*-* } .-1 }
+
+void test_2_notes (int i)
+{
+ char *p = i ? a + 3 : a + 5;
+ __builtin_memset (p, 0, 7); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+extern char b[8]; // dg-message at offset \\\[3, 6] into destination object 'b'" "note 1" }
+ // dg-message at offset \\\[4, 7] into destination object 'b'" "note 2" { target *-*-* } .-1 }
+ // dg-message at offset \\\[5, 8] into destination object 'b'" "note 3" { target *-*-* } .-2 }
+
+void test_3_notes (int i)
+{
+ char *p = i < 0 ? b + 3 : 0 < i ? b + 5 : b + 4;
+ __builtin_memset (p, 0, 7); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+extern char c[8]; // dg-message at offset \\\[3, 6] into destination object 'c'" "note 1" }
+ // dg-message at offset \\\[4, 7] into destination object 'c'" "note 2" { target *-*-* } .-1 }
+ // dg-message at offset \\\[5, 8] into destination object 'c'" "note 3" { target *-*-* } .-2 }
+ // dg-message at offset \\\[6, 8] into destination object 'c'" "note 3" { target *-*-* } .-2 }
+
+void test_4_notes (int i)
+{
+ char *p;
+ if (i < -1)
+ p = c + 3;
+ else if (i < 0)
+ p = c + 4;
+ else if (0 < i)
+ p = c + 6;
+ else
+ p = c + 5;
+
+ __builtin_memset (p, 0, 7); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+extern char d[8]; // dg-message at offset \\\[3, 6] into destination object 'd'" "note 1" }
+ // dg-message at offset \\\[4, 7] into destination object 'd'" "note 2" { target *-*-* } .-1 }
+ // dg-message at offset \\\[5, 8] into destination object 'd'" "note 3" { target *-*-* } .-2 }
+ // dg-message at offset \\\[6, 8] into destination object 'd'" "note 3" { target *-*-* } .-3 }
+ // dg-message at offset \\\[7, 8] into destination object 'd'" "note 3" { target *-*-* } .-4 }
+
+void test_5_notes (int i)
+{
+ char *p;
+ switch (i)
+ {
+ case -9: p = d + 3; break;
+ case -5: p = d + 4; break;
+ case 0: p = d + 5; break;
+ case 3: p = d + 6; break;
+ case 4: p = d + 7; break;
+ default: return;
+ }
+
+ __builtin_memset (p, 0, 7); // { dg-warning "-Wstringop-overflow" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-80.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-80.c
new file mode 100644
index 0000000..1628c2f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-80.c
@@ -0,0 +1,70 @@
+/* Verify that a separate note is issued for each offset into the same
+ object after a -Wstringop-overflow. Even though the warnings don't
+ need optimization the test enables it to verify they're still issued
+ with it. Wstringop-overflow-78.c verifies they're issued at -O0.
+ { dg-do compile }
+ { dg-options "-O2 -Wno-array-bounds" } */
+
+extern char a[8]; // dg-message at offset \\\[3, 6] into destination object 'a'" "note 1" }
+ // dg-message at offset \\\[5, 8] into destination object 'a'" "note 2" { target *-*-* } .-1 }
+
+void test_2_notes (int i)
+{
+ char *p = i ? a + 3 : a + 5;
+ __builtin_memset (p, 0, 7); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+extern char b[8]; // dg-message at offset \\\[3, 6] into destination object 'b'" "note 1" }
+ // dg-message at offset \\\[4, 7] into destination object 'b'" "note 2" { target *-*-* } .-1 }
+ // dg-message at offset \\\[5, 8] into destination object 'b'" "note 3" { target *-*-* } .-2 }
+
+void test_3_notes (int i)
+{
+ char *p = i < 0 ? b + 3 : 0 < i ? b + 5 : b + 4;
+ __builtin_memset (p, 0, 7); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+extern char c[8]; // dg-message at offset \\\[3, 6] into destination object 'c'" "note 1" }
+ // dg-message at offset \\\[4, 7] into destination object 'c'" "note 2" { target *-*-* } .-1 }
+ // dg-message at offset \\\[5, 8] into destination object 'c'" "note 3" { target *-*-* } .-2 }
+ // dg-message at offset \\\[6, 8] into destination object 'c'" "note 3" { target *-*-* } .-2 }
+
+void test_4_notes (int i)
+{
+ char *p;
+ if (i < -1)
+ p = c + 3;
+ else if (i < 0)
+ p = c + 4;
+ else if (0 < i)
+ p = c + 6;
+ else
+ p = c + 5;
+
+ __builtin_memset (p, 0, 7); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+extern char d[8]; // dg-message at offset \\\[3, 6] into destination object 'd'" "note 1" }
+ // dg-message at offset \\\[4, 7] into destination object 'd'" "note 2" { target *-*-* } .-1 }
+ // dg-message at offset \\\[5, 8] into destination object 'd'" "note 3" { target *-*-* } .-2 }
+ // dg-message at offset \\\[6, 8] into destination object 'd'" "note 3" { target *-*-* } .-3 }
+ // dg-message at offset \\\[7, 8] into destination object 'd'" "note 3" { target *-*-* } .-4 }
+
+void test_5_notes (int i)
+{
+ char *p;
+ switch (i)
+ {
+ case -9: p = d + 3; break;
+ case -5: p = d + 4; break;
+ case 0: p = d + 5; break;
+ case 3: p = d + 6; break;
+ case 4: p = d + 7; break;
+ default: return;
+ }
+
+ __builtin_memset (p, 0, 7); // { dg-warning "-Wstringop-overflow" }
+}