public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <rguenther@suse.de>
To: Jakub Jelinek <jakub@redhat.com>
Cc: Martin Uecker <uecker@tugraz.at>,
	"Joseph S. Myers" <josmyers@redhat.com>,
	 gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c, v3: Fix ICE with -g and -std=c23 related to incomplete types [PR114361]
Date: Mon, 15 Apr 2024 13:33:18 +0200 (CEST)	[thread overview]
Message-ID: <r8pp90qs-9285-oqp4-n200-2rq2514q315o@fhfr.qr> (raw)
In-Reply-To: <Zh0F4mLGO5WXGBM0@tucnak>

On Mon, 15 Apr 2024, Jakub Jelinek wrote:

> On Mon, Apr 15, 2024 at 10:05:58AM +0200, Jakub Jelinek wrote:
> > On Mon, Apr 15, 2024 at 10:02:25AM +0200, Richard Biener wrote:
> > > > Though, haven't managed to reproduce it with -O2 -flto -std=c23
> > > > struct S;
> > > > typedef struct S **V[10];
> > > > V **foo (int x) { return 0; }
> > > > struct S { int s; };
> > > > either.
> > > > So, maybe let's drop the ipa-free-lang-data.cc part?
> > > > Seems fld_incomplete_type_of uses fld_type_variant which should
> > > > copy over TYPE_CANONICAL.
> > > 
> > > If you have a testcase that still triggers it would be nice to see it.
> > 
> > I don't, that is why I'm now suggesting to just drop that hunk.
> 
> Actually no, I've just screwed up something in my testing.
> One can reproduce it easily with -O2 -flto 20021205-1.c -std=c23
> if the ipa-free-lang-data.cc hunk is removed.
> This happens when fld_incomplete_type_of is called on a POINTER_TYPE
> to RECORD_TYPE x, where the RECORD_TYPE x is not the TYPE_MAIN_VARIANT,
> but another variant created by set_underlying_type.  The
> c_update_type_canonical didn't touch TYPE_CANONICAL in those, I was too
> afraid I don't know what TYPE_CANONICAL should be for all variant types,
> so that TREE_TYPE (t) had TYPE_CANONICAL NULL.  But when we call
> fld_incomplete_type_of on that TREE_TYPE (t), it sees it isn't
> TYPE_MAIN_VARIANT, so calls
>   return (fld_type_variant
>           (fld_incomplete_type_of (TYPE_MAIN_VARIANT (t), fld), t, fld));
> but TYPE_MAIN_VARIANT (t) has already TYPE_CANONICAL (TYPE_MAIN_VARIANT (t))
> == TYPE_MAIN_VARIANT (t), that one has been completed on finish_struct.
> And so we trigger the assertion, because
> TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t))
> is no longer true, the former is non-NULL, the latter is NULL.
> 
> But looking at all the build_variant_type_copy callers and the call itself,
> the call itself sets TYPE_CANONICAL to the TYPE_CANONICAL of the type on
> which it is called and the only caller I can find that changes
> TYPE_CANONICAL sometimes is build_qualified_type.
> So, I'd hope that normally all variant types of an aggregate type (or
> pointer type) have the same TYPE_CANONICAL if they have the same TYPE_QUALS
> and if they have it different, they have TYPE_CANONICAL of
> build_qualified_type of the base TYPE_CANONICAL.

The middle-end assumes that TYPE_CANONICAL of all variant types are
the same, for TBAA purposes it immediately "puns" to
TYPE_CANONICAL (TYPE_MAIN_VARIANT (..)).  It also assumes that
the canonical type is not a variant type.  Note we never "honor"
TYPE_STRUCTURAL_EQUALITY_P on a variant type (because we don't look
at it, we only look at whether the main variant has
TYPE_STRUCTURAL_EQUALITY_P).

Thus, TYPE_CANONICAL of variant types in principle doesn't need to be
set (but not all places might go the extra step looking at the main
variant before accessing TYPE_CANONICAL).

Richard.

> With the following updated patch (ipa-free-lang-data.cc hunk removed,
> c_update_type_canonical function updated, plus removed trailing whitespace
> from tests),
> make check-gcc RUNTESTFLAGS="--target_board=unix/-std=gnu23 compile.exp='20021205-1.c 20040214-2.c 20060109-1.c pr113623.c pr46866.c pta-1.c' execute.exp='pr33870-1.c pr33870.c'"
> no longer ICEs (have just expected FAILs on 20040214-2.c which isn't
> compatible with C23) and make check-gcc -j32 doesn't regress compared
> to the unpatched one.
> 
> Is this ok for trunk if it passes full bootstrap/regtest?
> 
> 2024-04-15  Martin Uecker  <uecker@tugraz.at>
> 	    Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR lto/114574
> 	PR c/114361
> gcc/c/
> 	* c-decl.cc (shadow_tag_warned): For flag_isoc23 and code not
> 	ENUMERAL_TYPE use SET_TYPE_STRUCTURAL_EQUALITY.
> 	(parser_xref_tag): Likewise.
> 	(start_struct): For flag_isoc23 use SET_TYPE_STRUCTURAL_EQUALITY.
> 	(c_update_type_canonical): New function.
> 	(finish_struct): Put NULL as second == operand rather than first.
> 	Assert TYPE_STRUCTURAL_EQUALITY_P.  Call c_update_type_canonical.
> 	* c-typeck.cc (composite_type_internal): Use
> 	SET_TYPE_STRUCTURAL_EQUALITY.  Formatting fix.
> gcc/testsuite/
> 	* gcc.dg/pr114574-1.c: New test.
> 	* gcc.dg/pr114574-2.c: New test.
> 	* gcc.dg/pr114361.c: New test.
> 	* gcc.dg/c23-tag-incomplete-1.c: New test.
> 	* gcc.dg/c23-tag-incomplete-2.c: New test.
> 
> --- gcc/c/c-decl.cc.jj	2024-04-09 09:29:04.824520299 +0200
> +++ gcc/c/c-decl.cc	2024-04-15 12:26:43.000790475 +0200
> @@ -5051,6 +5051,8 @@ shadow_tag_warned (const struct c_declsp
>  	      if (t == NULL_TREE)
>  		{
>  		  t = make_node (code);
> +		  if (flag_isoc23 && code != ENUMERAL_TYPE)
> +		    SET_TYPE_STRUCTURAL_EQUALITY (t);
>  		  pushtag (input_location, name, t);
>  		}
>  	    }
> @@ -8809,6 +8811,8 @@ parser_xref_tag (location_t loc, enum tr
>       the forward-reference will be altered into a real type.  */
>  
>    ref = make_node (code);
> +  if (flag_isoc23 && code != ENUMERAL_TYPE)
> +    SET_TYPE_STRUCTURAL_EQUALITY (ref);
>    if (code == ENUMERAL_TYPE)
>      {
>        /* Give the type a default layout like unsigned int
> @@ -8910,6 +8914,8 @@ start_struct (location_t loc, enum tree_
>    if (ref == NULL_TREE || TREE_CODE (ref) != code)
>      {
>        ref = make_node (code);
> +      if (flag_isoc23)
> +	SET_TYPE_STRUCTURAL_EQUALITY (ref);
>        pushtag (loc, name, ref);
>      }
>  
> @@ -9347,6 +9353,45 @@ is_flexible_array_member_p (bool is_last
>    return false;
>  }
>  
> +/* Recompute TYPE_CANONICAL for variants of the type including qualified
> +   versions of the type and related pointer types after an aggregate type
> +   has been finalized.
> +   Will not update array types, pointers to array types, function
> +   types and other derived types created while the type was still
> +   incomplete, those will remain TYPE_STRUCTURAL_EQUALITY_P.  */
> +
> +static void
> +c_update_type_canonical (tree t)
> +{
> +  for (tree x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
> +    {
> +      if (x != t && TYPE_STRUCTURAL_EQUALITY_P (x))
> +	{
> +	  if (TYPE_QUALS (x) == TYPE_QUALS (t))
> +	    TYPE_CANONICAL (x) = TYPE_CANONICAL (t);
> +	  else if (TYPE_CANONICAL (t) != t
> +		   || check_qualified_type (x, t, TYPE_QUALS (x)))
> +	    TYPE_CANONICAL (x)
> +	      = build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x));
> +	  else
> +	    TYPE_CANONICAL (x) = x;
> +	}
> +      else if (x != t)
> +	continue;
> +      for (tree p = TYPE_POINTER_TO (x); p; p = TYPE_NEXT_PTR_TO (p))
> +	{
> +	  if (!TYPE_STRUCTURAL_EQUALITY_P (p))
> +	    continue;
> +	  if (TYPE_CANONICAL (x) != x || TYPE_REF_CAN_ALIAS_ALL (p))
> +	    TYPE_CANONICAL (p)
> +	      = build_pointer_type_for_mode (TYPE_CANONICAL (x), TYPE_MODE (p),
> +					     false);
> +	  else
> +	    TYPE_CANONICAL (p) = p;
> +	  c_update_type_canonical (p);
> +	}
> +    }
> +}
>  
>  /* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
>     LOC is the location of the RECORD_TYPE or UNION_TYPE's definition.
> @@ -9695,11 +9740,12 @@ finish_struct (location_t loc, tree t, t
>    /* Set type canonical based on equivalence class.  */
>    if (flag_isoc23)
>      {
> -      if (NULL == c_struct_htab)
> +      if (c_struct_htab == NULL)
>  	c_struct_htab = hash_table<c_struct_hasher>::create_ggc (61);
>  
>        hashval_t hash = c_struct_hasher::hash (t);
>  
> +      gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
>        tree *e = c_struct_htab->find_slot_with_hash (t, hash, INSERT);
>        if (*e)
>  	TYPE_CANONICAL (t) = *e;
> @@ -9708,6 +9754,7 @@ finish_struct (location_t loc, tree t, t
>  	  TYPE_CANONICAL (t) = t;
>  	  *e = t;
>  	}
> +      c_update_type_canonical (t);
>      }
>  
>    tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
> --- gcc/c/c-typeck.cc.jj	2024-02-08 11:17:37.035662909 +0100
> +++ gcc/c/c-typeck.cc	2024-04-12 17:17:33.029950025 +0200
> @@ -532,6 +532,7 @@ composite_type_internal (tree t1, tree t
>  	  /* Otherwise, create a new type node and link it into the cache.  */
>  
>  	  tree n = make_node (code1);
> +	  SET_TYPE_STRUCTURAL_EQUALITY (n);
>  	  TYPE_NAME (n) = TYPE_NAME (t1);
>  
>  	  struct composite_cache cache2 = { t1, t2, n, cache };
> @@ -590,7 +591,8 @@ composite_type_internal (tree t1, tree t
>  	  TYPE_STUB_DECL (n) = pushdecl (build_decl (input_location, TYPE_DECL,
>  						     NULL_TREE, n));
>  
> -	  n = finish_struct(input_location, n, fields, attributes, NULL, &expr);
> +	  n = finish_struct (input_location, n, fields, attributes, NULL,
> +			     &expr);
>  
>  	  n = qualify_type (n, t1);
>  
> --- gcc/testsuite/gcc.dg/pr114574-1.c.jj	2024-04-12 13:57:28.647782827 +0200
> +++ gcc/testsuite/gcc.dg/pr114574-1.c	2024-04-12 13:57:28.647782827 +0200
> @@ -0,0 +1,7 @@
> +/* PR lto/114574
> + * { dg-do compile }
> + * { dg-options "-flto" } */
> +
> +const struct S * x;
> +struct S {};
> +void f(const struct S **);
> --- gcc/testsuite/gcc.dg/pr114574-2.c.jj	2024-04-12 13:57:28.647782827 +0200
> +++ gcc/testsuite/gcc.dg/pr114574-2.c	2024-04-12 13:57:28.647782827 +0200
> @@ -0,0 +1,7 @@
> +/* PR lto/114574
> + * { dg-do compile }
> + * { dg-options "-flto -std=c23" } */
> +
> +const struct S * x;
> +struct S {};
> +void f(const struct S **);
> --- gcc/testsuite/gcc.dg/pr114361.c.jj	2024-04-12 13:57:28.684782327 +0200
> +++ gcc/testsuite/gcc.dg/pr114361.c	2024-04-12 13:57:28.684782327 +0200
> @@ -0,0 +1,10 @@
> +/* PR c/114361 */
> +/* { dg-do compile } */
> +/* { dg-options "-std=gnu23 -g" } */
> +
> +void f()
> +{
> +    typedef struct foo bar;
> +    typedef __typeof( ({ (struct foo { bar *x; }){ }; }) ) wuz;
> +    struct foo { wuz *x; };
> +}
> --- gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c.jj	2024-04-12 13:57:28.684782327 +0200
> +++ gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c	2024-04-12 13:57:28.684782327 +0200
> @@ -0,0 +1,11 @@
> +/* { dg-do compile }
> + * { dg-options "-std=c23 -g" } */
> +
> +struct a;
> +typedef struct a b;
> +
> +void g() {
> +    struct a { b* x; };
> +}
> +
> +struct a { b* x; };
> --- gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c.jj	2024-04-12 13:57:28.684782327 +0200
> +++ gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c	2024-04-12 13:57:28.684782327 +0200
> @@ -0,0 +1,11 @@
> +/* { dg-do compile }
> + * { dg-options "-std=c23 -g" } */
> +
> +struct a;
> +typedef struct a b;
> +
> +void f() {
> +	extern struct a { b* x; } t;
> +}
> +
> +extern struct a { b* x; } t;
> 
> 
> 	Jakub
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

  reply	other threads:[~2024-04-15 11:33 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-16 21:36 c23 type compatibility rules, v3 Martin Uecker
2023-11-16 21:38 ` [PATCH 1/4] c23: tag compatibility rules for struct and unions Martin Uecker
2023-11-23 23:17   ` Joseph Myers
2023-11-16 21:38 ` [PATCH 2/4] c23: tag compatibility rules for enums Martin Uecker
2023-11-23 23:26   ` Joseph Myers
2023-11-16 21:39 ` [PATCH 3/4] c23: aliasing of compatible tagged types Martin Uecker
2023-11-23 23:47   ` Joseph Myers
2023-11-26 22:48     ` Martin Uecker
2023-11-27  7:46       ` Richard Biener
2023-11-28  1:00       ` Joseph Myers
2023-11-28  6:49         ` Martin Uecker
2023-11-28 10:47         ` Richard Biener
2023-11-28 11:51           ` Martin Uecker
2023-11-16 21:40 ` [PATCH 4/4] c23: construct composite type for " Martin Uecker
2023-11-27 13:16 ` [V4] [C PATCH 1/4] c23: tag compatibility rules for struct and unions Martin Uecker
2023-12-14 20:53   ` Joseph Myers
2023-11-27 13:16 ` [V4] [PATCH 2/4] c23: tag compatibility rules for enums Martin Uecker
2023-12-14 20:58   ` Joseph Myers
2023-11-27 13:16 ` [V4] [PATCH 3/4] c23: aliasing of compatible tagged types Martin Uecker
2023-12-14 21:10   ` Joseph Myers
2023-11-27 13:16 ` [V4] [PATCH 4/4] c23: construct composite type for " Martin Uecker
2023-12-17 17:41 ` [V5] [C PATCH 1/4] c23: tag compatibility rules for struct and unions Martin Uecker
2023-12-19 21:48   ` Joseph Myers
2023-12-17 17:42 ` [V5] [C PATCH 2/4] c23: tag compatibility rules for enums Martin Uecker
2023-12-19 21:50   ` Joseph Myers
2023-12-17 17:42 ` [V5] [C PATCH 3/4] c23: aliasing of compatible tagged types Martin Uecker
2023-12-19 22:02   ` Joseph Myers
2023-12-17 17:42 ` [V5] [C PATCH 4/4] c23: construct composite type for " Martin Uecker
2023-12-19 22:25   ` Joseph Myers
2023-12-21 21:47 ` [V6] " Martin Uecker
2023-12-22 16:27   ` Joseph Myers
2023-12-27 19:23 ` [C PATCH] C: Fix type compatibility for structs with variable sized fields Martin Uecker
2023-12-29 15:57   ` Joseph Myers
2024-01-27 16:10 ` Fix ICE with -g and -std=c23 when forming composite types [PR113438] Martin Uecker
2024-01-29 20:27   ` Joseph Myers
2024-04-02 18:54 ` [C PATCH] Fix ICE with -g and -std=c23 related to incomplete types [PR114361] Martin Uecker
2024-04-02 20:31   ` Joseph Myers
2024-04-02 19:02 ` [C PATCH] fix aliasing for structures/unions with incomplete types Martin Uecker
2024-04-02 20:42   ` Joseph Myers
2024-04-02 21:22     ` Martin Uecker
2024-04-03 15:33       ` Joseph Myers
2024-04-14 12:30 ` [C PATCH, v2] Fix ICE with -g and -std=c23 related to incomplete types [PR114361] Martin Uecker
2024-04-14 12:38   ` Martin Uecker
2024-04-15  6:55   ` Richard Biener
2024-04-15  7:38     ` Jakub Jelinek
2024-04-15  7:59       ` Jakub Jelinek
2024-04-15  8:02         ` Richard Biener
2024-04-15  8:05           ` Jakub Jelinek
2024-04-15 10:48             ` [PATCH] c, v3: " Jakub Jelinek
2024-04-15 11:33               ` Richard Biener [this message]
2024-04-16  7:20                 ` Jakub Jelinek
2024-04-19 20:39               ` Joseph Myers
2024-04-15  7:03   ` [C PATCH, v2] " Jakub Jelinek
2024-05-18 13:27 ` [C PATCH] Fix for some variably modified types not being recognized [PR114831] Martin Uecker
2024-05-18 13:29   ` Martin Uecker
2024-05-20 21:18   ` Joseph Myers
2024-05-18 20:18 ` [C PATCH] Fix for redeclared enumerator initialized with different type [PR115109] Martin Uecker
2024-05-19 10:24   ` [C PATCH, v2] " Martin Uecker
2024-05-20 21:30     ` Joseph Myers
2024-05-21  5:40       ` Martin Uecker
2024-05-23 20:51         ` Joseph Myers
2024-05-21 12:18   ` [C PATCH]: allow aliasing of compatible types derived from enumeral types [PR115157] Martin Uecker
2024-05-23 20:59     ` Joseph Myers
2024-05-23 21:30       ` Ian Lance Taylor
2024-05-23 21:47         ` Martin Uecker
2024-05-23 21:53           ` Ian Lance Taylor
2024-05-24  5:56             ` Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=r8pp90qs-9285-oqp4-n200-2rq2514q315o@fhfr.qr \
    --to=rguenther@suse.de \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=josmyers@redhat.com \
    --cc=uecker@tugraz.at \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).