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

Reply via email to