Re: -Wcast-qual consistency with initialization conversion and double pointer types

2024-06-16 Thread Martin Uecker via Gcc


I think it should not warn about:

char *x;
*(char * volatile *)&x;

as this is regular qualifier adding and this is
a bug in GCC.

I would guess it looks at all qualifiers added at
all level but should ignore the one on the first level.

Martin


Am Samstag, dem 15.06.2024 um 10:17 -0700 schrieb Ryan Libby via Gcc:
> I'm not a C language expert and I'm looking for advice on whether a
> -Wcast-qual diagnostic in one situation and not another is intentional
> behavior.
> 
> Here's a set of examples (same as attachment).
> 
> % cat cast-qual-example.c
> #define F(name, type, qual) \
> typedef type t_##name;  \
> void name(void) {   \
> t_##name x = 0, y, z;   \
> y = *(t_##name qual *)&x;   \
> z = *(t_##name qual *){&x}; \
> }
> 
> F(fcc, char, const)
> F(fpc, char *, const)
> F(fcv, char, volatile)
> F(fpv, char *, volatile)
> 
> void fpv2(void) {
> char *x = 0, *y, *z;
> y = *(char * volatile *)&x;
> z = *(char * volatile *){&x};
> }
> 
> void eg1(void) {
> /* Adapted from -Wcast-qual doc */
> char v0 = 'v';
> char *v1 = &v0;
> char **p = &v1;
> /* p is char ** value.  */
> char * volatile *q = (char * volatile *) p;
> /* Assignment of volatile pointer to char is OK. */
> char u0 = 'u';
> char * volatile u1 = &u0;
> *q = u1;
> /* Now *q is accessed through a non-volatile-qualified pointer. */
> *p = 0;
> }
> 
> void eg2(void) {
> char v = 'v';
> char *p = &v;
> /* p is char * value.  */
> char volatile *q = (char volatile *) p;
> /* Assignment of volatile char is OK (and also plain char). */
> char volatile u = 'u';
> *q = u;
> /* Now *q is accessed through a non-volatile-qualified pointer. */
> *p = 0;
> }
> 
> % gcc13 -std=c17 -Wall -Wextra -Wcast-qual -Wno-unused -c
> cast-qual-example.c -o /dev/null
> cast-qual-example.c: In function 'fpv':
> cast-qual-example.c:5:14: warning: to be safe all intermediate
> pointers in cast from 'char **' to 'char * volatile*' must be 'const'
> qualified [-Wcast-qual]
> 5 | y = *(t_##name qual *)&x;   \
>   |  ^
> cast-qual-example.c:12:1: note: in expansion of macro 'F'
>12 | F(fpv, char *, volatile)
>   | ^
> cast-qual-example.c: In function 'fpv2':
> cast-qual-example.c:16:14: warning: to be safe all intermediate
> pointers in cast from 'char **' to 'char * volatile*' must be 'const'
> qualified [-Wcast-qual]
>16 | y = *(char * volatile *)&x;
>   |  ^
> cast-qual-example.c: In function 'eg1':
> cast-qual-example.c:26:30: warning: to be safe all intermediate
> pointers in cast from 'char **' to 'char * volatile*' must be 'const'
> qualified [-Wcast-qual]
>26 | char * volatile *q = (char * volatile *) p;
>   |  ^
> % clang -std=c17 -Wall -Wextra -Wcast-qual -Wno-unused -c
> cast-qual-example.c -o /dev/null
> %
> 
> The macro and typedef are to illustrate the point, they aren't otherwise
> needed, and fpv2 shows the same thing without them.
> 
> So, in the conversion of char ** to char * volatile *, the cast before
> the assignment of y is diagnosed, but the conversion in the
> initialization of the compound literal for the assignment of z is not.
> 
> First, is the cast construct actually different from the initialization
> construct in terms of safety?  I would think not, but maybe I am
> missing something.
> 
> I think that both assignment expressions in fpv as a whole are
> ultimately safe, considering also the immediate dereference of the
> temporary outer pointer value.
> 
> In eg1 and eg2 I modified examples from the -Wcast-qual documentation.
> eg1 is diagnosed, eg2 is not.
> 
> I think that the *p assignment in eg1 might be undefined behavior
> (6.7.3, referring to an object with volatile-qualified type (*q) through
> an lvalue without volatile-qualified type (*p)).
> 
> But then I don't get why the same wouldn't be true if we take away the
> inner pointer and repeat the exercise with plain char (eg1 vs eg2).
> 
> So, what's going on here?  Is the gcc behavior intentional?  Is it
> consistent?  And is there a recommended way to construct a temporary
> volatile pointer to an object (which may itself be a pointer) without
> tripping -Wcast-qual, without just casting away type information (as in,
> without intermediate casts through void *, uintptr_t, etc), and
> preferably also without undefined behavior?
> 
> I have checked that the behavior is the same with current sources and
> -std=c23 (gcc (GCC) 15.0.0 20240614 (experimental)).
> 
> P.s. I have seen gcc bug 84166 that advises that the -Wcast-qual warning
> from the cast is intentional in that case.  I think this case is
> different because in that case the qualifiers are on the innermost type.
> 
> Thank you,
> 
> Ryan L

Re: -Wcast-qual consistency with initialization conversion and double pointer types

2024-06-16 Thread Ryan Libby via Gcc
On Sun, Jun 16, 2024 at 12:33 AM Martin Uecker  wrote:
>
>
> I think it should not warn about:
>
> char *x;
> *(char * volatile *)&x;
>
> as this is regular qualifier adding and this is
> a bug in GCC.
>

I can file a bug if it is indeed one.

> I would guess it looks at all qualifiers added at
> all level but should ignore the one on the first level.
>
> Martin

It looks to me like handle_warn_cast_qual() does ignore qualifiers at
the outermost level, but it is only examining the cast itself (so e.g.
it will not complain about cast from char ** to char ** volatile).

If by first level, you mean the level after the outermost, that would
solve my issue, but I'm unsure if it provides the originally intended
warnings.  On the other hand, there is also currently no warning for a
cast from char const ** to char const * const *.  Maybe this was
likewise intended to be accepted as "regular qualifier adding".

If you mean in the context of the larger expression which dereferences
the outer pointer, this seems more clearly not dangerous, but glancing
through the code, I'm not sure if we have that context where the warning
is generated.

Ryan


check_qualified_type

2024-06-16 Thread Martin Uecker via Gcc



I am trying to understand what check_qualified_type
does exactly. The direct comparison of TYPE_NAMES seems incorrect
for C and its use is c_update_type_canonical then causes
PR114930 and PR115502.  In the later function I think
it is not really needed and I guess one could simply remove
it, but I wonder if it works incorrectly in other cases 
too?


Martin




gcc-15-20240616 is now available

2024-06-16 Thread GCC Administrator via Gcc
Snapshot gcc-15-20240616 is now available on
  https://gcc.gnu.org/pub/gcc/snapshots/15-20240616/
and on various mirrors, see https://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 15 git branch
with the following options: git://gcc.gnu.org/git/gcc.git branch master 
revision 33caee556c130b2dcf311480314e942a43d6b368

You'll find:

 gcc-15-20240616.tar.xz   Complete GCC

  SHA256=8e34ba90f4ad8b5480d695a56031590508ab0d9dfc085900ff331da71db99b68
  SHA1=292bf9bfbf4666dbb7a31b479fe2a1329bb7509a

Diffs from 15-20240609 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-15
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.


Re: check_qualified_type

2024-06-16 Thread Richard Biener via Gcc
On Sun, 16 Jun 2024, Martin Uecker wrote:

> 
> 
> I am trying to understand what check_qualified_type
> does exactly. The direct comparison of TYPE_NAMES seems incorrect
> for C and its use is c_update_type_canonical then causes
> PR114930 and PR115502.  In the later function I think
> it is not really needed and I guess one could simply remove
> it, but I wonder if it works incorrectly in other cases 
> too?

TYPE_NAMES is compared because IIRC typedefs are recorded as variants
and 'const T' isn't the same as 'const int' with typedef int T.

Richard.


Re: GCC 12.4 Release Candidate available from gcc.gnu.org

2024-06-16 Thread Richard Biener via Gcc
On Fri, 14 Jun 2024, Jonathan Wakely wrote:

> On Thu, 13 Jun 2024 at 09:14, Richard Biener via Gcc  wrote:
> >
> >
> > The first release candidate for GCC 12.4 is available from
> >
> > https://gcc.gnu.org/pub/gcc/snapshots/12.4.0-RC-20240613/
> >
> > and shortly its mirrors.  It has been generated from git commit
> > r12-10557-g6693b1f3929771.
> >
> > I have so far bootstrapped and tested the release candidate on
> > x86_64-linux.
> > Please test it and report any issues to bugzilla.
> >
> > If all goes well, we'd like to release 12.4 on Thursday, June 20th.
> 
> I've just been informed of a regression for --disable-hosted-libstdcxx
> (i.e. freestanding) builds which I've fixed for trunk, 14 and 13 with:
> https://gcc.gnu.org/pipermail/gcc-patches/2024-June/654726.html
> 
> It would be nice to fix it for gcc 12.4, although it's not essential
> (it was already broken for 14.1 and 13.3).

I think that change is OK to pick.

Thanks,
Richard.


Re: check_qualified_type

2024-06-16 Thread Martin Uecker via Gcc
Am Montag, dem 17.06.2024 um 08:01 +0200 schrieb Richard Biener via Gcc:
> On Sun, 16 Jun 2024, Martin Uecker wrote:
> 
> > 
> > 
> > I am trying to understand what check_qualified_type
> > does exactly. The direct comparison of TYPE_NAMES seems incorrect
> > for C and its use is c_update_type_canonical then causes
> > PR114930 and PR115502.  In the later function I think
> > it is not really needed and I guess one could simply remove
> > it, but I wonder if it works incorrectly in other cases 
> > too?
> 
> TYPE_NAMES is compared because IIRC typedefs are recorded as variants
> and 'const T' isn't the same as 'const int' with typedef int T.

so if it is intentional that it differentiates between 

struct foo

and

typedef struct foo bar

then I will change c_update_type_canonical to not use it,
because both types should have the same TYPE_CANONICAL

Martin