public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* check_qualified_type
@ 2024-06-16 20:22 Martin Uecker
  2024-06-17  6:01 ` check_qualified_type Richard Biener
  0 siblings, 1 reply; 10+ messages in thread
From: Martin Uecker @ 2024-06-16 20:22 UTC (permalink / raw)
  To: gcc; +Cc: Joseph Myers, Richard Biener, Jakub Jelinek



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



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: check_qualified_type
  2024-06-16 20:22 check_qualified_type Martin Uecker
@ 2024-06-17  6:01 ` Richard Biener
  2024-06-17  6:31   ` check_qualified_type Martin Uecker
  2024-06-17 16:01   ` check_qualified_type Jonathan Wakely
  0 siblings, 2 replies; 10+ messages in thread
From: Richard Biener @ 2024-06-17  6:01 UTC (permalink / raw)
  To: Martin Uecker; +Cc: gcc, Joseph Myers, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 559 bytes --]

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.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: check_qualified_type
  2024-06-17  6:01 ` check_qualified_type Richard Biener
@ 2024-06-17  6:31   ` Martin Uecker
  2024-06-17 12:42     ` check_qualified_type Richard Biener
  2024-06-17 16:01   ` check_qualified_type Jonathan Wakely
  1 sibling, 1 reply; 10+ messages in thread
From: Martin Uecker @ 2024-06-17  6:31 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc, Joseph Myers, Jakub Jelinek

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



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: check_qualified_type
  2024-06-17  6:31   ` check_qualified_type Martin Uecker
@ 2024-06-17 12:42     ` Richard Biener
  2024-06-17 12:57       ` check_qualified_type Jakub Jelinek
  0 siblings, 1 reply; 10+ messages in thread
From: Richard Biener @ 2024-06-17 12:42 UTC (permalink / raw)
  To: Martin Uecker; +Cc: gcc, Joseph Myers, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 1153 bytes --]

On Mon, 17 Jun 2024, Martin Uecker wrote:

> 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

The check is supposed to differentiate between variants and all variants
have the same TYPE_CANONICAL so I'm not sure why you considered using
this function for canonical type compute?

Richard.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: check_qualified_type
  2024-06-17 12:42     ` check_qualified_type Richard Biener
@ 2024-06-17 12:57       ` Jakub Jelinek
  2024-06-17 13:33         ` check_qualified_type Martin Uecker
  0 siblings, 1 reply; 10+ messages in thread
From: Jakub Jelinek @ 2024-06-17 12:57 UTC (permalink / raw)
  To: Richard Biener; +Cc: Martin Uecker, gcc, Joseph Myers

On Mon, Jun 17, 2024 at 02:42:05PM +0200, Richard Biener 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
> 
> The check is supposed to differentiate between variants and all variants
> have the same TYPE_CANONICAL so I'm not sure why you considered using
> this function for canonical type compute?

I've done that and that was because build_qualified_type uses that
predicate, where qualified types created by build_qualified_type have
as TYPE_CANONICAL the qualified type of the main variant of the canonical
type, while in all other cases TYPE_CANONICAL is just the main variant of
the type.
Guess we could also just do
          if (TYPE_QUALS (x) == TYPE_QUALS (t))
            TYPE_CANONICAL (x) = TYPE_CANONICAL (t);
          else if (TYPE_CANONICAL (t) != t
		   || TYPE_QUALS (x) != TYPE_QUALS (TYPE_CANONICAL (t)))
            TYPE_CANONICAL (x)
              = build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x));
          else
            TYPE_CANONICAL (x) = x;
or so.

	Jakub


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: check_qualified_type
  2024-06-17 12:57       ` check_qualified_type Jakub Jelinek
@ 2024-06-17 13:33         ` Martin Uecker
  2024-06-17 13:40           ` check_qualified_type Jakub Jelinek
  0 siblings, 1 reply; 10+ messages in thread
From: Martin Uecker @ 2024-06-17 13:33 UTC (permalink / raw)
  To: Jakub Jelinek, Richard Biener; +Cc: gcc, Joseph Myers

Am Montag, dem 17.06.2024 um 14:57 +0200 schrieb Jakub Jelinek:
> On Mon, Jun 17, 2024 at 02:42:05PM +0200, Richard Biener 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
> > 
> > The check is supposed to differentiate between variants and all variants
> > have the same TYPE_CANONICAL so I'm not sure why you considered using
> > this function for canonical type compute?
> 
> I've done that and that was because build_qualified_type uses that
> predicate, where qualified types created by build_qualified_type have
> as TYPE_CANONICAL the qualified type of the main variant of the canonical
> type, while in all other cases TYPE_CANONICAL is just the main variant of
> the type.
> Guess we could also just do
>           if (TYPE_QUALS (x) == TYPE_QUALS (t))
>             TYPE_CANONICAL (x) = TYPE_CANONICAL (t);
>           else if (TYPE_CANONICAL (t) != t
> 		   || TYPE_QUALS (x) != TYPE_QUALS (TYPE_CANONICAL (t)))
>             TYPE_CANONICAL (x)
>               = build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x));
>           else
>             TYPE_CANONICAL (x) = x;
> 

Ok, that works. I think the final "else" is then then impossible to reach
and can be eliminated as well, because if TYPE_CANONICAL (t) == t then 
TYPE_QUALS (x) == TYPE_QUALS (TYPE_CANONICAL (t)) is identical to
TYPE_QUALS (x) == TYPE_QUALS (t) which is the first case.

Martin




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: check_qualified_type
  2024-06-17 13:33         ` check_qualified_type Martin Uecker
@ 2024-06-17 13:40           ` Jakub Jelinek
  2024-06-17 13:53             ` check_qualified_type Martin Uecker
  0 siblings, 1 reply; 10+ messages in thread
From: Jakub Jelinek @ 2024-06-17 13:40 UTC (permalink / raw)
  To: Martin Uecker; +Cc: Richard Biener, gcc, Joseph Myers

On Mon, Jun 17, 2024 at 03:33:05PM +0200, Martin Uecker wrote:
> > I've done that and that was because build_qualified_type uses that
> > predicate, where qualified types created by build_qualified_type have
> > as TYPE_CANONICAL the qualified type of the main variant of the canonical
> > type, while in all other cases TYPE_CANONICAL is just the main variant of
> > the type.
> > Guess we could also just do
> >           if (TYPE_QUALS (x) == TYPE_QUALS (t))
> >             TYPE_CANONICAL (x) = TYPE_CANONICAL (t);
> >           else if (TYPE_CANONICAL (t) != t
> > 		   || TYPE_QUALS (x) != TYPE_QUALS (TYPE_CANONICAL (t)))
> >             TYPE_CANONICAL (x)
> >               = build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x));
> >           else
> >             TYPE_CANONICAL (x) = x;
> > 
> 
> Ok, that works. I think the final "else" is then then impossible to reach
> and can be eliminated as well, because if TYPE_CANONICAL (t) == t then 
> TYPE_QUALS (x) == TYPE_QUALS (TYPE_CANONICAL (t)) is identical to
> TYPE_QUALS (x) == TYPE_QUALS (t) which is the first case.

If c_update_type_canonical is only ever called for the main variants of the
type and they always have !TYPE_QUALS (t), then yes.
But if we rely on that, perhaps we should gcc_checking_assert that.
So
  gcc_checking_assert (t == TYPE_MAIN_VARIANT (t) && !TYPE_QUALS (t));
or something similar at the start of the function.
Then we could also change the
  for (tree x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
to
  for (tree x = t; x; x = TYPE_NEXT_VARIANT (x))
and
	  if (TYPE_QUALS (x) == TYPE_QUALS (t))
...
to
	  if (!TYPE_QUALS (x))
	    TYPE_CANONICAL (x) = TYPE_CANONICAL (t);
	  else
	    build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x));

	Jakub


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: check_qualified_type
  2024-06-17 13:40           ` check_qualified_type Jakub Jelinek
@ 2024-06-17 13:53             ` Martin Uecker
  2024-06-17 14:01               ` check_qualified_type Jakub Jelinek
  0 siblings, 1 reply; 10+ messages in thread
From: Martin Uecker @ 2024-06-17 13:53 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Richard Biener, gcc, Joseph Myers

Am Montag, dem 17.06.2024 um 15:40 +0200 schrieb Jakub Jelinek:
> On Mon, Jun 17, 2024 at 03:33:05PM +0200, Martin Uecker wrote:
> > > I've done that and that was because build_qualified_type uses that
> > > predicate, where qualified types created by build_qualified_type have
> > > as TYPE_CANONICAL the qualified type of the main variant of the canonical
> > > type, while in all other cases TYPE_CANONICAL is just the main variant of
> > > the type.
> > > Guess we could also just do
> > >           if (TYPE_QUALS (x) == TYPE_QUALS (t))
> > >             TYPE_CANONICAL (x) = TYPE_CANONICAL (t);
> > >           else if (TYPE_CANONICAL (t) != t
> > > 		   || TYPE_QUALS (x) != TYPE_QUALS (TYPE_CANONICAL (t)))
> > >             TYPE_CANONICAL (x)
> > >               = build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x));
> > >           else
> > >             TYPE_CANONICAL (x) = x;
> > > 
> > 
> > Ok, that works. I think the final "else" is then then impossible to reach
> > and can be eliminated as well, because if TYPE_CANONICAL (t) == t then 
> > TYPE_QUALS (x) == TYPE_QUALS (TYPE_CANONICAL (t)) is identical to
> > TYPE_QUALS (x) == TYPE_QUALS (t) which is the first case.
> 
> If c_update_type_canonical is only ever called for the main variants of the
> type and they always have !TYPE_QUALS (t), then yes.
> But if we rely on that, perhaps we should gcc_checking_assert that.
> So
>   gcc_checking_assert (t == TYPE_MAIN_VARIANT (t) && !TYPE_QUALS (t));
> or something similar at the start of the function.

It calls itself recursively on pointers to the type.  But to
me the third branch looks dead in any case, because the first
two cover all possibilities.

Martin

> Then we could also change the
>   for (tree x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
> to
>   for (tree x = t; x; x = TYPE_NEXT_VARIANT (x))
> and
> 	  if (TYPE_QUALS (x) == TYPE_QUALS (t))
> ...
> to
> 	  if (!TYPE_QUALS (x))
> 	    TYPE_CANONICAL (x) = TYPE_CANONICAL (t);
> 	  else
> 	    build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x));
> 





> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: check_qualified_type
  2024-06-17 13:53             ` check_qualified_type Martin Uecker
@ 2024-06-17 14:01               ` Jakub Jelinek
  0 siblings, 0 replies; 10+ messages in thread
From: Jakub Jelinek @ 2024-06-17 14:01 UTC (permalink / raw)
  To: Martin Uecker; +Cc: Richard Biener, gcc, Joseph Myers

On Mon, Jun 17, 2024 at 03:53:41PM +0200, Martin Uecker wrote:
> > If c_update_type_canonical is only ever called for the main variants of the
> > type and they always have !TYPE_QUALS (t), then yes.
> > But if we rely on that, perhaps we should gcc_checking_assert that.
> > So
> >   gcc_checking_assert (t == TYPE_MAIN_VARIANT (t) && !TYPE_QUALS (t));
> > or something similar at the start of the function.
> 
> It calls itself recursively on pointers to the type.  But to
> me the third branch looks dead in any case, because the first
> two cover all possibilities.

Yes, but the pointers built by build_pointer_type should still be hopefully
the unqualified versions, if one wants a qualified pointer, that would be
build_qualified_type (build_pointer_type (...), ...)

The checks cover all the possibilities only if the canonical type has
the same quals as t.

> > Then we could also change the
> >   for (tree x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
> > to
> >   for (tree x = t; x; x = TYPE_NEXT_VARIANT (x))
> > and
> > 	  if (TYPE_QUALS (x) == TYPE_QUALS (t))
> > ...
> > to
> > 	  if (!TYPE_QUALS (x))
> > 	    TYPE_CANONICAL (x) = TYPE_CANONICAL (t);
> > 	  else
> > 	    build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x));
> > 

	Jakub


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: check_qualified_type
  2024-06-17  6:01 ` check_qualified_type Richard Biener
  2024-06-17  6:31   ` check_qualified_type Martin Uecker
@ 2024-06-17 16:01   ` Jonathan Wakely
  1 sibling, 0 replies; 10+ messages in thread
From: Jonathan Wakely @ 2024-06-17 16:01 UTC (permalink / raw)
  To: Richard Biener; +Cc: Martin Uecker, gcc, Joseph Myers, Jakub Jelinek

On Mon, 17 Jun 2024 at 07:02, Richard Biener via Gcc <gcc@gcc.gnu.org> wrote:
>
> 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.

Presumably it's also relevant for this example:

typedef signed int sint;

struct S {
  int i : 2;
  sint s : 2;
};

Here it's impl-defined whether i is signed, but s must be signed.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2024-06-17 16:01 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-16 20:22 check_qualified_type Martin Uecker
2024-06-17  6:01 ` check_qualified_type Richard Biener
2024-06-17  6:31   ` check_qualified_type Martin Uecker
2024-06-17 12:42     ` check_qualified_type Richard Biener
2024-06-17 12:57       ` check_qualified_type Jakub Jelinek
2024-06-17 13:33         ` check_qualified_type Martin Uecker
2024-06-17 13:40           ` check_qualified_type Jakub Jelinek
2024-06-17 13:53             ` check_qualified_type Martin Uecker
2024-06-17 14:01               ` check_qualified_type Jakub Jelinek
2024-06-17 16:01   ` check_qualified_type Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).