Message ID | ri635oubq7c.fsf@suse.cz |
---|---|
State | New |
Headers | show |
Series | sra: Fix corner case of total scalarization with virtual inheritance (PR 102505) | expand |
On Thu, Oct 21, 2021 at 12:57 PM Martin Jambor <mjambor@suse.cz> wrote: > > Hi, > > PR 102505 is a situation where of SRA takes its initial top-level > access size from a get_ref_base_and_extent called on a COMPONENT_REF, > and thus derived frm the FIELD_DECL, which however does not include a > virtual base. Total scalarization then goes on traversing the type, > which however has virtual base past the non-virtual bits, tricking SRA > to create sub-accesses outside of the supposedly encompassing > accesses, which in turn triggers the verifier within the pass. > > The patch below fixes that by failing total scalarization when this > situation is detected. > > Bootstrapped and tested on x86_64-linux, OK for trunk and (after testing > there) on the branches? OK. > Thanks, > > Martin > > > gcc/ChangeLog: > > 2021-10-20 Martin Jambor <mjambor@suse.cz> > > PR tree-optimization/102505 > * tree-sra.c (totally_scalarize_subtree): Check that the > encountered field fits within the acces we would like to put it > in. > > gcc/testsuite/ChangeLog: > > 2021-10-20 Martin Jambor <mjambor@suse.cz> > > PR tree-optimization/102505 > * g++.dg/torture/pr102505.C: New test. > --- > gcc/testsuite/g++.dg/torture/pr102505.C | 15 +++++++++++++++ > gcc/tree-sra.c | 2 ++ > 2 files changed, 17 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/torture/pr102505.C > > diff --git a/gcc/testsuite/g++.dg/torture/pr102505.C b/gcc/testsuite/g++.dg/torture/pr102505.C > new file mode 100644 > index 00000000000..a846751a0d6 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/torture/pr102505.C > @@ -0,0 +1,15 @@ > +struct D { int i; int pad alignas(16); }; > +struct B : virtual D > +{ > + int j =84; > + int k =84; > +}; > + > +struct C: B { }; > + > +int main() > +{ > + C c; > + if (c.j != 84 || c.k != 84) > + __builtin_abort(); > +} > diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c > index 9b786e29e4e..f561e1a2133 100644 > --- a/gcc/tree-sra.c > +++ b/gcc/tree-sra.c > @@ -3288,6 +3288,8 @@ totally_scalarize_subtree (struct access *root) > continue; > > HOST_WIDE_INT pos = root->offset + int_bit_position (fld); > + if (pos + fsize > root->size) > + return false; > enum total_sra_field_state > state = total_should_skip_creating_access (root, > &last_seen_sibling, > -- > 2.33.0 >
diff --git a/gcc/testsuite/g++.dg/torture/pr102505.C b/gcc/testsuite/g++.dg/torture/pr102505.C new file mode 100644 index 00000000000..a846751a0d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr102505.C @@ -0,0 +1,15 @@ +struct D { int i; int pad alignas(16); }; +struct B : virtual D +{ + int j =84; + int k =84; +}; + +struct C: B { }; + +int main() +{ + C c; + if (c.j != 84 || c.k != 84) + __builtin_abort(); +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 9b786e29e4e..f561e1a2133 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -3288,6 +3288,8 @@ totally_scalarize_subtree (struct access *root) continue; HOST_WIDE_INT pos = root->offset + int_bit_position (fld); + if (pos + fsize > root->size) + return false; enum total_sra_field_state state = total_should_skip_creating_access (root, &last_seen_sibling,