diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc index f994388a96a..53a2e35133d 100644 --- a/gcc/ipa-modref.cc +++ b/gcc/ipa-modref.cc @@ -3004,6 +3004,9 @@ analyze_parms (modref_summary *summary, modref_summary_lto *summary_lto, (past, ecf_flags, VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))); + /* Store merging can produce reads when combining together multiple + bitfields. See PR111613. */ + past &= ~(EAF_NO_DIRECT_READ | EAF_NO_INDIRECT_READ); if (dump_file && (flags | past) != flags && !(flags & EAF_UNUSED)) { fprintf (dump_file, diff --git a/gcc/testsuite/gcc.c-torture/pr111613.c b/gcc/testsuite/gcc.c-torture/pr111613.c new file mode 100644 index 00000000000..1ea1c4dec07 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/pr111613.c @@ -0,0 +1,29 @@ +#include +#include + +struct bitfield { + unsigned int field1 : 1; + unsigned int field2 : 1; + unsigned int field3 : 1; +}; + +__attribute__((noinline)) static void +set_field1_and_field2(struct bitfield *b) { + b->field1 = 1; + b->field2 = 1; +} + +__attribute__((noinline)) static struct bitfield * +new_bitfield(void) { + struct bitfield *b = (struct bitfield *)malloc(sizeof(*b)); + b->field3 = 1; + set_field1_and_field2(b); + return b; +} + +int main(void) { + struct bitfield *b = new_bitfield(); + if (b->field3 != 1) + __builtin_abort (); + return 0; +}