From bf0a63a1f47525d1c466dbb84616dcb72010affa Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 27 Nov 2020 11:23:45 +0100 Subject: [PATCH] gimple-fold: Fix another __builtin_clear_padding ICE When playing with __builtin_bit_cast, I have noticed __builtin_clear_padding ICE on the G class below. The artificial field with D type has offset 0 and size 8 bytes, but the following artificial field with E type has offset 0 and size 0, so it triggers the asserts that we don't move current position backwards. Fixed by ignoring is_empty_type (TREE_TYPE (field)) fields, all of their bits are padding which is what is added when skipping over to next field anyway. 2020-11-27 Jakub Jelinek PR libstdc++/88101 * gimple-fold.c (clear_padding_type): Ignore fields with is_empty_type types. * g++.dg/torture/builtin-clear-padding-3.C: New test. --- gcc/gimple-fold.c | 2 ++ .../g++.dg/torture/builtin-clear-padding-3.C | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 gcc/testsuite/g++.dg/torture/builtin-clear-padding-3.C diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index a821b649bf8..1f3d80e2881 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -4533,6 +4533,8 @@ clear_padding_type (clear_padding_struct *buf, tree type, HOST_WIDE_INT sz) "well defined padding bits for %qs", field, "__builtin_clear_padding"); } + else if (is_empty_type (TREE_TYPE (field))) + continue; else { HOST_WIDE_INT pos = int_byte_position (field); diff --git a/gcc/testsuite/g++.dg/torture/builtin-clear-padding-3.C b/gcc/testsuite/g++.dg/torture/builtin-clear-padding-3.C new file mode 100644 index 00000000000..d528196bf2d --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/builtin-clear-padding-3.C @@ -0,0 +1,24 @@ +/* PR libstdc++/88101 */ + +struct D { int a; int : 24; int b : 8; }; +struct E {}; +struct F { char c, d, e; }; +struct G : public D, E, F { int f; } g1, g2; + +__attribute__((noipa)) void +foo (G *g) +{ + g->a = -1; g->b = -1; g->c = -1; g->d = -1; g->e = -1; g->f = -1; +} + +int +main () +{ + __builtin_memset (&g2, -1, sizeof (g2)); + foo (&g1); + foo (&g2); + __builtin_clear_padding (&g2); + if (__builtin_memcmp (&g1, &g2, sizeof (g1))) + __builtin_abort (); + return 0; +} -- 2.30.2