| /* PR 85643 - attribute nonstring fails to squash -Wstringop-truncation |
| warning |
| { dg-do compile } |
| { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ |
| |
| #define strncpy __builtin_strncpy |
| |
| struct A { |
| char a[16 + 1]; |
| }; |
| |
| struct B { |
| char a[16] __attribute__ ((__nonstring__)); |
| }; |
| |
| struct B* |
| test_memarray (const struct A *s) |
| { |
| static struct B b; |
| strncpy (b.a, s->a, sizeof b.a); |
| return &b; |
| } |
| |
| const char* |
| test_array (const char *s) |
| { |
| static char a[80] __attribute__ ((__nonstring__)); |
| strncpy (a, s, sizeof a); |
| return a; |
| } |
| |
| const char* |
| test_array_idx (const char *s) |
| { |
| static char a[80] __attribute__ ((__nonstring__)); |
| char *p __attribute__ ((__nonstring__)) = &a[20]; |
| strncpy (p, s, 60); /* { dg-bogus "-Wstringop-truncation" } */ |
| return a; |
| } |
| |
| const char* |
| test_array_off (const char *s) |
| { |
| static char a[80] __attribute__ ((__nonstring__)); |
| char *p __attribute__ ((__nonstring__)) = a + 20; |
| strncpy (p, s, 60); /* { dg-bogus "-Wstringop-truncation" } */ |
| return a; |
| } |
| |
| struct B* |
| test_memarray_cstidx_idx (const char *s) |
| { |
| static struct B b[2]; |
| char *p __attribute__ ((__nonstring__)) = &b[1].a[4]; |
| |
| /* The destination below is represented as &MEM[(void *)&a + 20B] and |
| which (in general) doesn't make it possible to determine what member |
| it refers to. */ |
| strncpy (p, s, sizeof b[1].a - 4); /* { dg-bogus "-Wstringop-truncation" "" { xfail *-*-*} } */ |
| return b; |
| } |
| |
| struct B* |
| test_memarray_cstidx_off (const char *s) |
| { |
| static struct B b[2]; |
| char *p __attribute__ ((__nonstring__)) = b[1].a + 4; |
| |
| /* Same as above. */ |
| strncpy (p, s, sizeof b[1].a - 4); /* { dg-bogus "-Wstringop-truncation" "" { xfail *-*-*} } */ |
| return b; |
| } |
| |
| struct B* |
| test_memarray_varidx_idx (const char *s, int i) |
| { |
| static struct B b[3]; |
| char *p __attribute__ ((__nonstring__)) = &b[i].a[4]; |
| strncpy (p, s, sizeof b[i].a - 4); |
| return b; |
| } |
| |
| struct B* |
| test_memarray_varidx_off (const char *s, int i) |
| { |
| static struct B b[3]; |
| char *p __attribute__ ((__nonstring__)) = b[i].a + 4; |
| strncpy (p, s, sizeof b[i].a - 4); |
| return b; |
| } |