On Mon, Jun 17, 2024 at 07:09:03PM +0200, Jakub Jelinek wrote: > Hi! > > The warning code uses %D to print the ARRAY_REF first operands. > That works in the most common case where those operands are decls, but > as can be seen on the following testcase, they can be other expressions > with array type. > Just changing %D to %E isn't enough, because then the diagnostics can > suggest something like > note: use '&(x) != 0 ? (int (*)[32])&a : (int (*)[32])&b[0] == &(y) != 0 ? > (int (*)[32])&a : (int (*)[32])&b[0]' to compare the addresses > which is a bad suggestion, the %E printing doesn't know that the > warning code will want to add & before it and [0] after it. > So, the following patch adds ()s around the operand as well, but does > that only for non-decls, for decls keeps it as &arr[0] like before. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk > and release branches?
Ok, thanks. > 2024-06-17 Jakub Jelinek <ja...@redhat.com> > > PR c/115290 > * c-warn.cc (do_warn_array_compare): Use %E rather than %D for > printing op0 and op1; if those operands aren't decls, also print > parens around them. > > * c-c++-common/Warray-compare-3.c: New test. > > --- gcc/c-family/c-warn.cc.jj 2024-06-04 13:19:03.371609456 +0200 > +++ gcc/c-family/c-warn.cc 2024-06-17 15:07:09.005737065 +0200 > @@ -3832,11 +3832,16 @@ do_warn_array_compare (location_t locati > /* C doesn't allow +arr. */ > if (c_dialect_cxx ()) > inform (location, "use unary %<+%> which decays operands to pointers " > - "or %<&%D[0] %s &%D[0]%> to compare the addresses", > - op0, op_symbol_code (code), op1); > + "or %<&%s%E%s[0] %s &%s%E%s[0]%> to compare the addresses", > + DECL_P (op0) ? "" : "(", op0, DECL_P (op0) ? "" : ")", > + op_symbol_code (code), > + DECL_P (op1) ? "" : "(", op1, DECL_P (op1) ? "" : ")"); > else > - inform (location, "use %<&%D[0] %s &%D[0]%> to compare the addresses", > - op0, op_symbol_code (code), op1); > + inform (location, > + "use %<&%s%E%s[0] %s &%s%E%s[0]%> to compare the addresses", > + DECL_P (op0) ? "" : "(", op0, DECL_P (op0) ? "" : ")", > + op_symbol_code (code), > + DECL_P (op1) ? "" : "(", op1, DECL_P (op1) ? "" : ")"); > } > } > > --- gcc/testsuite/c-c++-common/Warray-compare-3.c.jj 2024-06-17 > 15:13:57.098422635 +0200 > +++ gcc/testsuite/c-c++-common/Warray-compare-3.c 2024-06-17 > 15:13:24.339849049 +0200 > @@ -0,0 +1,13 @@ > +/* PR c/115290 */ > +/* { dg-do compile } */ > +/* { dg-options "-Warray-compare" } */ > + > +int a[32][32], b[32][32]; > + > +int > +foo (int x, int y) > +{ > + return (x ? a : b) == (y ? a : b); /* { dg-warning "comparison between two > arrays" } */ > +/* { dg-message "use '&\\\(\[^\n\r]*\\\)\\\[0\\\] == > &\\\(\[^\n\r]*\\\)\\\[0\\\]' to compare the addresses" "" { target c } .-1 } > */ > +/* { dg-message "use unary '\\\+' which decays operands to pointers or > '&\\\(\[^\n\r]*\\\)\\\[0\\\] == &\\\(\[^\n\r]*\\\)\\\[0\\\]' to compare the > addresses" "" { target c++ } .-2 } */ > +} > > Jakub > Marek