diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index d2a0f6ddf19..3548c914482 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -4242,7 +4242,8 @@ clear_padding_flush (clear_padding_struct *buf, bool full) i -= wordsize; continue; } - for (size_t j = i; j < i + wordsize && j < end; j++) + size_t endsize = end - i > wordsize ? wordsize : end - i; + for (size_t j = i; j < i + endsize; j++) { if (buf->buf[j]) { @@ -4271,12 +4272,12 @@ clear_padding_flush (clear_padding_struct *buf, bool full) if (padding_bytes) { if (nonzero_first == 0 - && nonzero_last == wordsize + && nonzero_last == endsize && all_ones) { /* All bits are padding and we had some padding before too. Just extend it. */ - padding_bytes += wordsize; + padding_bytes += endsize; continue; } if (all_ones && nonzero_first == 0) @@ -4316,7 +4317,7 @@ clear_padding_flush (clear_padding_struct *buf, bool full) if (nonzero_first == wordsize) /* All bits in a word are 0, there are no padding bits. */ continue; - if (all_ones && nonzero_last == wordsize) + if (all_ones && nonzero_last == endsize) { /* All bits between nonzero_first and end of word are padding bits, start counting padding_bytes. */ @@ -4358,7 +4359,7 @@ clear_padding_flush (clear_padding_struct *buf, bool full) j = k; } } - if (nonzero_last == wordsize) + if (nonzero_last == endsize) padding_bytes = nonzero_last - zero_last; continue; } @@ -4832,6 +4833,7 @@ clear_padding_type (clear_padding_struct *buf, tree type, buf->off = 0; buf->size = 0; clear_padding_emit_loop (buf, elttype, end, for_auto_init); + off += sz; buf->base = base; buf->sz = prev_sz; buf->align = prev_align; diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-1.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-1.c index 6b01a5614b5..f739963cc4d 100644 --- a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-1.c +++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-1.c @@ -1,4 +1,5 @@ /* PR libstdc++/88101 */ +/* { dg-do run } */ int i1, i2; long double l1, l2; diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-2.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-2.c index 1188bc07ed2..099f202ebc7 100644 --- a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-2.c +++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-2.c @@ -1,4 +1,5 @@ /* PR libstdc++/88101 */ +/* { dg-do run } */ typedef int T __attribute__((aligned (16384))); struct S { char a; short b; long double c; T d; T e; long long f; }; diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c index edb7c8eb555..27bf8f6dd73 100644 --- a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c +++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c @@ -1,4 +1,5 @@ /* PR libstdc++/88101 */ +/* { dg-do run } */ union V { char a; signed char b; unsigned char c; }; struct T { char a; int b; union V c; }; diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-4.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-4.c index 9cb202fc690..ebc58932738 100644 --- a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-4.c +++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-4.c @@ -1,6 +1,6 @@ -/* { dg-require-effective-target alloca } */ - /* PR libstdc++/88101 */ +/* { dg-do run } */ +/* { dg-require-effective-target alloca } */ struct S { char a; short b; char c; }; diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-5.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-5.c index d5dbafe1c74..3f7d40fddf8 100644 --- a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-5.c +++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-5.c @@ -1,4 +1,5 @@ /* PR libstdc++/88101 */ +/* { dg-do run } */ struct S { char a; short b; char c; } s1[24], s2[24]; struct T { char a; long long b; char c; struct S d[3]; long long e; char f; } t1, t2; diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-6.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-6.c new file mode 100644 index 00000000000..db1f00eca73 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-6.c @@ -0,0 +1,28 @@ +/* PR middle-end/115527 */ +/* { dg-do run } */ + +struct T { struct S { double a; signed char b; long c; } d[3]; int e; } t1, t2; + +__attribute__((noipa)) void +foo (struct T *t) +{ + for (int i = 0; i < 3; ++i) + { + t->d[i].a = 1. + 3 * i; + t->d[i].b = 2 + 3 * i; + t->d[i].c = 3 + 3 * i; + } + t->e = 10; +} + +int +main () +{ + __builtin_memset (&t2, -1, sizeof (t2)); + foo (&t1); + foo (&t2); + __builtin_clear_padding (&t2); + if (__builtin_memcmp (&t1, &t2, sizeof (t1))) + __builtin_abort (); + return 0; +}