Message ID | 20170220203804.GG1849@tucnak |
---|---|
State | New |
Headers | show |
OK. On Mon, Feb 20, 2017 at 12:38 PM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > When generic is unshared, we generally don't unshare DECL_VALUE_EXPRs, > so those are assumed to be not shared, otherwise as in the testcase > we can clear first argument of a COMPOUND_EXPR after it has been gimplified > in one use and by that clobbering all others. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2017-02-20 Jakub Jelinek <jakub@redhat.com> > > PR sanitizer/79589 > * decl.c: Include gimplify.h. > (cp_finish_decomp): Make sure there is no sharing of trees > in between DECL_VALUE_EXPR of decomposition decls. > > * g++.dg/ubsan/pr79589.C: New test. > > --- gcc/cp/decl.c.jj 2017-02-17 18:29:21.000000000 +0100 > +++ gcc/cp/decl.c 2017-02-20 11:45:55.281636544 +0100 > @@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. > #include "plugin.h" > #include "cilk.h" > #include "builtins.h" > +#include "gimplify.h" > > /* Possible cases of bad specifiers type used by bad_specifiers. */ > enum bad_spec_place { > @@ -7467,7 +7468,7 @@ cp_finish_decomp (tree decl, tree first, > { > TREE_TYPE (v[i]) = eltype; > layout_decl (v[i], 0); > - tree t = dexp; > + tree t = unshare_expr (dexp); > t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, > eltype, t, size_int (i), NULL_TREE, > NULL_TREE); > @@ -7486,7 +7487,7 @@ cp_finish_decomp (tree decl, tree first, > { > TREE_TYPE (v[i]) = eltype; > layout_decl (v[i], 0); > - tree t = dexp; > + tree t = unshare_expr (dexp); > t = build1_loc (DECL_SOURCE_LOCATION (v[i]), > i ? IMAGPART_EXPR : REALPART_EXPR, eltype, > t); > @@ -7504,7 +7505,7 @@ cp_finish_decomp (tree decl, tree first, > { > TREE_TYPE (v[i]) = eltype; > layout_decl (v[i], 0); > - tree t = dexp; > + tree t = unshare_expr (dexp); > convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]), > &t, size_int (i)); > t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, > @@ -7603,7 +7604,8 @@ cp_finish_decomp (tree decl, tree first, > continue; > else > { > - tree tt = finish_non_static_data_member (field, t, NULL_TREE); > + tree tt = finish_non_static_data_member (field, unshare_expr (t), > + NULL_TREE); > if (REFERENCE_REF_P (tt)) > tt = TREE_OPERAND (tt, 0); > TREE_TYPE (v[i]) = TREE_TYPE (tt); > --- gcc/testsuite/g++.dg/ubsan/pr79589.C.jj 2017-02-20 11:51:36.732130221 +0100 > +++ gcc/testsuite/g++.dg/ubsan/pr79589.C 2017-02-20 11:52:09.012704729 +0100 > @@ -0,0 +1,13 @@ > +// PR sanitizer/79589 > +// { dg-do compile } > +// { dg-options "-fsanitize=undefined -std=c++1z" } > + > +struct A { char a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r; } a[64]; > + > +void > +foo () > +{ > + int z = 0; > + for (auto & [ b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s ] : a) > + z += b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s; > +} > > Jakub
--- gcc/cp/decl.c.jj 2017-02-17 18:29:21.000000000 +0100 +++ gcc/cp/decl.c 2017-02-20 11:45:55.281636544 +0100 @@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. #include "plugin.h" #include "cilk.h" #include "builtins.h" +#include "gimplify.h" /* Possible cases of bad specifiers type used by bad_specifiers. */ enum bad_spec_place { @@ -7467,7 +7468,7 @@ cp_finish_decomp (tree decl, tree first, { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); - tree t = dexp; + tree t = unshare_expr (dexp); t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE); @@ -7486,7 +7487,7 @@ cp_finish_decomp (tree decl, tree first, { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); - tree t = dexp; + tree t = unshare_expr (dexp); t = build1_loc (DECL_SOURCE_LOCATION (v[i]), i ? IMAGPART_EXPR : REALPART_EXPR, eltype, t); @@ -7504,7 +7505,7 @@ cp_finish_decomp (tree decl, tree first, { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); - tree t = dexp; + tree t = unshare_expr (dexp); convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]), &t, size_int (i)); t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, @@ -7603,7 +7604,8 @@ cp_finish_decomp (tree decl, tree first, continue; else { - tree tt = finish_non_static_data_member (field, t, NULL_TREE); + tree tt = finish_non_static_data_member (field, unshare_expr (t), + NULL_TREE); if (REFERENCE_REF_P (tt)) tt = TREE_OPERAND (tt, 0); TREE_TYPE (v[i]) = TREE_TYPE (tt); --- gcc/testsuite/g++.dg/ubsan/pr79589.C.jj 2017-02-20 11:51:36.732130221 +0100 +++ gcc/testsuite/g++.dg/ubsan/pr79589.C 2017-02-20 11:52:09.012704729 +0100 @@ -0,0 +1,13 @@ +// PR sanitizer/79589 +// { dg-do compile } +// { dg-options "-fsanitize=undefined -std=c++1z" } + +struct A { char a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r; } a[64]; + +void +foo () +{ + int z = 0; + for (auto & [ b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s ] : a) + z += b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s; +}