Message ID | 20200505222853.GU8462@tucnak |
---|---|
State | New |
Headers | show |
Series | c++: Avoid strict_aliasing_warning on dependent types or expressions [PR94951] | expand |
On 5/5/20 6:28 PM, Jakub Jelinek wrote: > Hi! > > The following testcase gets a bogus warning during build_base_path, > when cp_build_indirect_ref* calls strict_aliasing_warning with a dependent > expression. IMHO calling get_alias_set etc. on dependent types feels wrong > to me, we should just defer the warnings in those cases until instantiation > and only handle the cases where neither type nor expr are dependent. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? OK. > 2020-05-05 Jakub Jelinek <jakub@redhat.com> > > PR c++/94951 > * typeck.c (cp_strict_aliasing_warning): New function. > (cp_build_indirect_ref_1, build_reinterpret_cast_1): Use > it instead of strict_aliasing_warning. > > * g++.dg/warn/Wstrict-aliasing-bogus-tmpl.C: New test. > > --- gcc/cp/typeck.c.jj 2020-03-19 22:54:38.393744684 +0100 > +++ gcc/cp/typeck.c 2020-05-05 18:12:21.964090624 +0200 > @@ -3318,6 +3318,22 @@ build_x_indirect_ref (location_t loc, tr > return rval; > } > > +/* Like c-family strict_aliasing_warning, but don't warn for dependent > + types or expressions. */ > + > +static bool > +cp_strict_aliasing_warning (location_t loc, tree type, tree expr) > +{ > + if (processing_template_decl) > + { > + tree e = expr; > + STRIP_NOPS (e); > + if (dependent_type_p (type) || type_dependent_expression_p (e)) > + return false; > + } > + return strict_aliasing_warning (loc, type, expr); > +} > + > /* The implementation of the above, and of indirection implied by other > constructs. If DO_FOLD is true, fold away INDIRECT_REF of ADDR_EXPR. */ > > @@ -3360,10 +3376,10 @@ cp_build_indirect_ref_1 (location_t loc, > /* If a warning is issued, mark it to avoid duplicates from > the backend. This only needs to be done at > warn_strict_aliasing > 2. */ > - if (warn_strict_aliasing > 2) > - if (strict_aliasing_warning (EXPR_LOCATION (ptr), > - type, TREE_OPERAND (ptr, 0))) > - TREE_NO_WARNING (ptr) = 1; > + if (warn_strict_aliasing > 2 > + && cp_strict_aliasing_warning (EXPR_LOCATION (ptr), > + type, TREE_OPERAND (ptr, 0))) > + TREE_NO_WARNING (ptr) = 1; > } > > if (VOID_TYPE_P (t)) > @@ -7777,7 +7793,7 @@ build_reinterpret_cast_1 (location_t loc > expr = cp_build_addr_expr (expr, complain); > > if (warn_strict_aliasing > 2) > - strict_aliasing_warning (EXPR_LOCATION (expr), type, expr); > + cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr); > > if (expr != error_mark_node) > expr = build_reinterpret_cast_1 > @@ -7891,7 +7907,7 @@ build_reinterpret_cast_1 (location_t loc > > if (warn_strict_aliasing <= 2) > /* strict_aliasing_warning STRIP_NOPs its expr. */ > - strict_aliasing_warning (EXPR_LOCATION (expr), type, expr); > + cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr); > > return build_nop_reinterpret (type, expr); > } > --- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-tmpl.C.jj 2020-05-05 18:18:43.408320000 +0200 > +++ gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-tmpl.C 2020-05-05 18:17:35.178352212 +0200 > @@ -0,0 +1,12 @@ > +// PR c++/94951 > +// { dg-do compile } > +// { dg-options "-O2 -Wall" } > + > +struct A { int a; }; > +template <int N> > +struct B : public A > +{ > + static B<N> foo () { B<N> t; t.a = 4; return t; } // { dg-bogus "dereferencing type-punned pointer will break strict-aliasing rules" } > +}; > + > +B<0> b = B<0>::foo (); > > Jakub >
--- gcc/cp/typeck.c.jj 2020-03-19 22:54:38.393744684 +0100 +++ gcc/cp/typeck.c 2020-05-05 18:12:21.964090624 +0200 @@ -3318,6 +3318,22 @@ build_x_indirect_ref (location_t loc, tr return rval; } +/* Like c-family strict_aliasing_warning, but don't warn for dependent + types or expressions. */ + +static bool +cp_strict_aliasing_warning (location_t loc, tree type, tree expr) +{ + if (processing_template_decl) + { + tree e = expr; + STRIP_NOPS (e); + if (dependent_type_p (type) || type_dependent_expression_p (e)) + return false; + } + return strict_aliasing_warning (loc, type, expr); +} + /* The implementation of the above, and of indirection implied by other constructs. If DO_FOLD is true, fold away INDIRECT_REF of ADDR_EXPR. */ @@ -3360,10 +3376,10 @@ cp_build_indirect_ref_1 (location_t loc, /* If a warning is issued, mark it to avoid duplicates from the backend. This only needs to be done at warn_strict_aliasing > 2. */ - if (warn_strict_aliasing > 2) - if (strict_aliasing_warning (EXPR_LOCATION (ptr), - type, TREE_OPERAND (ptr, 0))) - TREE_NO_WARNING (ptr) = 1; + if (warn_strict_aliasing > 2 + && cp_strict_aliasing_warning (EXPR_LOCATION (ptr), + type, TREE_OPERAND (ptr, 0))) + TREE_NO_WARNING (ptr) = 1; } if (VOID_TYPE_P (t)) @@ -7777,7 +7793,7 @@ build_reinterpret_cast_1 (location_t loc expr = cp_build_addr_expr (expr, complain); if (warn_strict_aliasing > 2) - strict_aliasing_warning (EXPR_LOCATION (expr), type, expr); + cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr); if (expr != error_mark_node) expr = build_reinterpret_cast_1 @@ -7891,7 +7907,7 @@ build_reinterpret_cast_1 (location_t loc if (warn_strict_aliasing <= 2) /* strict_aliasing_warning STRIP_NOPs its expr. */ - strict_aliasing_warning (EXPR_LOCATION (expr), type, expr); + cp_strict_aliasing_warning (EXPR_LOCATION (expr), type, expr); return build_nop_reinterpret (type, expr); } --- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-tmpl.C.jj 2020-05-05 18:18:43.408320000 +0200 +++ gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-tmpl.C 2020-05-05 18:17:35.178352212 +0200 @@ -0,0 +1,12 @@ +// PR c++/94951 +// { dg-do compile } +// { dg-options "-O2 -Wall" } + +struct A { int a; }; +template <int N> +struct B : public A +{ + static B<N> foo () { B<N> t; t.a = 4; return t; } // { dg-bogus "dereferencing type-punned pointer will break strict-aliasing rules" } +}; + +B<0> b = B<0>::foo ();