[Bug c/81631] New: -Wcast-qual false positive for pointer to array

2017-07-31 Thread gcc17 at cwde dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81631

Bug ID: 81631
   Summary: -Wcast-qual false positive for pointer to array
   Product: gcc
   Version: 7.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: gcc17 at cwde dot de
  Target Milestone: ---

Hi,

--
typedef int footype[6];

extern void const * bar;

void baz(void)
{
  footype const * x;
  x = (footype const *) bar;
}
--

with -Wcast-qual, this yields

--
$ gcc -Wcast-qual -c foo.c
foo.c:12:7: warning: cast discards 'const' qualifier from pointer target type
[-Wcast-qual]
   x = (footype const *) bar;
   ^
--

If "footype" is any other type than an array, I don't get the warning. I tested
gcc 4.5.1, 6.3.0, 7.1.0, on cygwin and Debian, all show this behavior. clang
doesn't warn.

[Bug c/81631] -Wcast-qual false positive for pointer to array

2017-09-14 Thread gcc17 at cwde dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81631

--- Comment #3 from Tobias Jordan  ---
Hi,

thanks for taking a look, and thanks for your explanation. As far as I
understand it, it's somewhat intuitive that the qualifiers apply to array
elements and not the array type itself. What bugs me is that -Wcast-qual in
this case looks at the array type, not at the element type, to detect whether
qualifiers match.

My actual use case is more complicated than the first example. I'm doing some
kind of marshalling/unmarshalling:

const int (*bar(const int (*x)[6]))[6]
{
  const void * y = x;   /* (1) */
  /* y takes a journey... */
  return (const int (*)[6]) y;  /* (2) */
}

In this example, if I remove the "const" in (1), I get a warning for
"-Wdiscarded-array-qualifiers". If I make y a "const void *", I get the
"-Wcast-qual" warning in (2). In my opinion, using a "const void *" would be
the correct way to do it.

Actually, when I change the type of y to a "void*" and do an explicit cast in
(1), like in
  void * y = (void *) x;/* (1') */

I don't get any warning at all. Here, I would expect a "-Wcast-qual" warning:
before the cast, x is a pointer to an array of consts, so I couldn't modify the
pointer target. After the cast, I can, and don't get any warnings (but
undefined behaviour).

So my proposal for -Wcast-qual would be: when looking at pointer-to-array,
consider the qualifiers of the element type, not the array type, to detect
whether qualifiers match.

As a side note, clang seems to agree with me here:

$ clang -Wcast-qual -c foo.c
foo.c:3:24: warning: cast from 'int const (*)[6]' to 'void *' drops const
qualifier [-Wcast-qual]
   void * y = (void *) x;/* (1') */
   ^
1 warning generated.