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.
This commit is contained in:
Martin Sebor 2021-10-26 14:34:16 -06:00
parent 65f711203d
commit 88b504b7a8
7 changed files with 1410 additions and 4 deletions

View file

@ -2109,6 +2109,9 @@ private:
pass_waccess (pass_waccess &) = delete;
void operator= (pass_waccess &) = delete;
/* Check a call to an atomic built-in function. */
bool check_atomic_builtin (gcall *);
/* Check a call to a built-in function. */
bool check_builtin (gcall *);
@ -2681,6 +2684,87 @@ pass_waccess::check_memop_access (gimple *stmt, tree dest, tree src, tree size)
srcsize, dstsize, data.mode, &data);
}
/* Check a call STMT to an atomic or sync built-in. */
bool
pass_waccess::check_atomic_builtin (gcall *stmt)
{
tree callee = gimple_call_fndecl (stmt);
if (!callee)
return false;
/* The size in bytes of the access by the function, and the number
of the second argument to check (if any). */
unsigned bytes = 0, arg2 = UINT_MAX;
switch (DECL_FUNCTION_CODE (callee))
{
#define BUILTIN_ACCESS_SIZE_FNSPEC(N) \
BUILT_IN_ATOMIC_LOAD_ ## N: \
case BUILT_IN_SYNC_FETCH_AND_ADD_ ## N: \
case BUILT_IN_SYNC_FETCH_AND_SUB_ ## N: \
case BUILT_IN_SYNC_FETCH_AND_OR_ ## N: \
case BUILT_IN_SYNC_FETCH_AND_AND_ ## N: \
case BUILT_IN_SYNC_FETCH_AND_XOR_ ## N: \
case BUILT_IN_SYNC_FETCH_AND_NAND_ ## N: \
case BUILT_IN_SYNC_ADD_AND_FETCH_ ## N: \
case BUILT_IN_SYNC_SUB_AND_FETCH_ ## N: \
case BUILT_IN_SYNC_OR_AND_FETCH_ ## N: \
case BUILT_IN_SYNC_AND_AND_FETCH_ ## N: \
case BUILT_IN_SYNC_XOR_AND_FETCH_ ## N: \
case BUILT_IN_SYNC_NAND_AND_FETCH_ ## N: \
case BUILT_IN_SYNC_LOCK_TEST_AND_SET_ ## N: \
case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_ ## N: \
case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_ ## N: \
case BUILT_IN_SYNC_LOCK_RELEASE_ ## N: \
case BUILT_IN_ATOMIC_EXCHANGE_ ## N: \
case BUILT_IN_ATOMIC_STORE_ ## N: \
case BUILT_IN_ATOMIC_ADD_FETCH_ ## N: \
case BUILT_IN_ATOMIC_SUB_FETCH_ ## N: \
case BUILT_IN_ATOMIC_AND_FETCH_ ## N: \
case BUILT_IN_ATOMIC_NAND_FETCH_ ## N: \
case BUILT_IN_ATOMIC_XOR_FETCH_ ## N: \
case BUILT_IN_ATOMIC_OR_FETCH_ ## N: \
case BUILT_IN_ATOMIC_FETCH_ADD_ ## N: \
case BUILT_IN_ATOMIC_FETCH_SUB_ ## N: \
case BUILT_IN_ATOMIC_FETCH_AND_ ## N: \
case BUILT_IN_ATOMIC_FETCH_NAND_ ## N: \
case BUILT_IN_ATOMIC_FETCH_OR_ ## N: \
case BUILT_IN_ATOMIC_FETCH_XOR_ ## N: \
bytes = N; \
break; \
case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_ ## N: \
bytes = N; \
arg2 = 1
case BUILTIN_ACCESS_SIZE_FNSPEC (1);
break;
case BUILTIN_ACCESS_SIZE_FNSPEC (2);
break;
case BUILTIN_ACCESS_SIZE_FNSPEC (4);
break;
case BUILTIN_ACCESS_SIZE_FNSPEC (8);
break;
case BUILTIN_ACCESS_SIZE_FNSPEC (16);
break;
default:
return false;
}
tree size = build_int_cstu (sizetype, bytes);
tree dst = gimple_call_arg (stmt, 0);
check_memop_access (stmt, dst, NULL_TREE, size);
if (arg2 != UINT_MAX)
{
tree dst = gimple_call_arg (stmt, arg2);
check_memop_access (stmt, dst, NULL_TREE, size);
}
return true;
}
/* Check call STMT to a built-in function for invalid accesses. Return
true if a call has been handled. */
@ -2795,10 +2879,11 @@ pass_waccess::check_builtin (gcall *stmt)
}
default:
return false;
if (check_atomic_builtin (stmt))
return true;
break;
}
return true;
return false;
}
/* Returns the type of the argument ARGNO to function with type FNTYPE

View file

@ -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

View file

@ -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" }
}

View file

@ -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" }
}

View file

@ -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" }
}

View file

@ -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" }
}

View file

@ -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" }
}