blob: b7b2a5fc4bfc338c6be6dcc3f05a18d9a7a2f1a9 [file] [log] [blame]
/* PR middle-end/92721 - checking ICE on attribute access redeclaration
Test to verify the handling of attribute access combining multiple
declarations of the same function.
{ dg-do compile }
{ dg-options "-O0 -Wall -ftrack-macro-expansion=0" } */
#define RO(...) __attribute__ ((access (read_only, __VA_ARGS__)))
#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
#define WO(...) __attribute__ ((access (write_only, __VA_ARGS__)))
typedef __INT32_TYPE__ int32_t;
void RO (1) RO (1) rop1_ror2 (const int32_t*, const int32_t&);
void RO (1) RO (2) rop1_ror2 (const int32_t*, const int32_t&);
void RO (2) RO (1) rop1_ror2 (const int32_t*, const int32_t&);
void RO (2) RO (2) rop1_ror2 (const int32_t*, const int32_t&);
void RW (1) RW (1) rdwrp1_rdwrr2 (int32_t*, int32_t&);
void RW (1) RW (2) rdwrp1_rdwrr2 (int32_t*, int32_t&);
void RW (2) RW (1) rdwrp1_rdwrr2 (int32_t*, int32_t&);
void RW (2) RW (2) rdwrp1_rdwrr2 (int32_t*, int32_t&);
void WO (1) WO (1) wop1_wor2 (int32_t*, int32_t&);
void WO (1) WO (2) wop1_wor2 (int32_t*, int32_t&);
void WO (2) WO (1) wop1_wor2 (int32_t*, int32_t&);
void WO (2) WO (2) wop1_wor2 (int32_t*, int32_t&);
// Verify that everything works even with no optimization.
void call_rop1_ror2_O0 (void)
{
const int32_t x[1] = { };
rop1_ror2 (x, x[0]);
rop1_ror2 (x, x[1]); // { dg-warning "reading 4 bytes from a region of size 0" }
rop1_ror2 (x + 1, x[0]); // { dg-warning "reading 4 bytes from a region of size 0" }
}
void call_rdwrp1_rdwrr2_O0 (void)
{
int32_t x[1] = { };
rdwrp1_rdwrr2 (x, x[0]);
rdwrp1_rdwrr2 (x, x[1]); // { dg-warning "accessing 4 bytes in a region of size 0" }
rdwrp1_rdwrr2 (x + 1, x[0]); // { dg-warning "accessing 4 bytes in a region of size 0" }
}
void call_wop1_wor2_O0 (void)
{
int32_t x[1];
wop1_wor2 (x, x[0]);
wop1_wor2 (x, x[1]); // { dg-warning "writing 4 bytes into a region of size 0" }
wop1_wor2 (x + 1, x[0]); // { dg-warning "writing 4 bytes into a region of size 0" }
}
// Verify that everything still works with -O1.
#pragma GCC optimize "1"
void call_rop1_ror2_O1 (void)
{
const int32_t x[1] = { 1 };
const int32_t *p0 = x, &r0 = x[0];
const int32_t *p1 = (const int32_t*)((const char*)p0 + 1);
const int32_t &r2 = *(const int32_t*)((const char*)p1 + 1);
rop1_ror2 (x, x[0]);
rop1_ror2 (x, x[1]); // { dg-warning "reading 4 bytes from a region of size 0" }
rop1_ror2 (x + 1, x[0]); // { dg-warning "reading 4 bytes from a region of size 0" }
rop1_ror2 (p0, r0);
rop1_ror2 (p0, r2); // { dg-warning "reading 4 bytes from a region of size 2" }
rop1_ror2 (p1, r0); // { dg-warning "reading 4 bytes from a region of size 3" }
}
void call_rdwrp1_rdwrr2_O1 (void)
{
int32_t x[1] = { };
int32_t *p0 = x, &r0 = x[0];
int32_t *p1 = (int32_t*)((char*)p0 + 1);
int32_t &r2 = *(int32_t*)((char*)p1 + 1);
rdwrp1_rdwrr2 (x, x[0]);
rdwrp1_rdwrr2 (x, x[1]); // { dg-warning "accessing 4 bytes in a region of size 0" }
rdwrp1_rdwrr2 (x + 1, x[0]); // { dg-warning "accessing 4 bytes in a region of size 0" }
rdwrp1_rdwrr2 (p0, r0);
rdwrp1_rdwrr2 (p0, r2); // { dg-warning "accessing 4 bytes in a region of size 2" }
rdwrp1_rdwrr2 (p1, r0); // { dg-warning "accessing 4 bytes in a region of size 3" }
}
void call_wop1_wor2_O1 (void)
{
int32_t x[1];
int32_t *p0 = x, &r0 = x[0];
int32_t *p1 = (int32_t*)((char*)p0 + 1);
int32_t &r2 = *(int32_t*)((char*)p1 + 1);
wop1_wor2 (x, x[0]);
wop1_wor2 (x, x[1]); // { dg-warning "writing 4 bytes into a region of size 0" }
wop1_wor2 (x + 1, x[0]); // { dg-warning "writing 4 bytes into a region of size 0" }
wop1_wor2 (p0, r0);
wop1_wor2 (p0, r2); // { dg-warning "writing 4 bytes into a region of size 2" }
wop1_wor2 (p1, r0); // { dg-warning "writing 4 bytes into a region of size 3" }
}