From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by sourceware.org (Postfix) with ESMTPS id 067BD385840E for ; Sun, 26 May 2024 12:15:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 067BD385840E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 067BD385840E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::42e ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716725704; cv=none; b=AK59G2XlaYo2i9QJfiYvJM9WXsW4MZJJXJPwzg943SbL/ThIc87lNOwnrypWzxZOydqBEXspKY5UD8mkhU6ZDnIx4KeHOGT/+EF/f4Lh8wQ4pGjxb45/FuI8N/EIJ8Z7665b2F/VDTOgL32gARdCzbhumA32ql/qEf0vNTt989I= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716725704; c=relaxed/simple; bh=XYI8PGEVBRY7K2Dz+EWdXPXjhNJDV/z9OOTOPvdlkAc=; h=DKIM-Signature:Message-ID:Subject:From:To:Date:MIME-Version; b=LYYyNP63qj9S6IiGhP8lFmc6RG268w5rKnjM0dvIgzy1PDBUqLhXR16/RDSlV7jCYe6t7HxclbaQZFdbmFJF/Yza0MVafpkggEYcnzXCDKvLLXJAHbu+sTO9J/wyYZCamv5cGadhhJzl7S5Ao0pvFWV5AoibpGd9htEdSFSxVJg= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-wr1-x42e.google.com with SMTP id ffacd0b85a97d-354e0d4db6cso2734999f8f.0 for ; Sun, 26 May 2024 05:15:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1716725701; x=1717330501; darn=gcc.gnu.org; h=mime-version:user-agent:content-transfer-encoding:date:cc:to:from :subject:message-id:from:to:cc:subject:date:message-id:reply-to; bh=LABB0j8CIFdPWnuU0WFLYqhxIxkTz9JgVM44A/J5thE=; b=I1xSAzSkysGRmCjZHY423nmLby2dGeE/1Qz8Q187fkGBa2NmHTV6aIdjIqNnN4Hpju rcX1wL0IbpmYzRn43TGmuf6AHuvPfSME9feR2BGKp4NNhmPV0hpQhGLI2r4NpooURh4W oQXqK8yv/J3Tkde09o4ZmImlKlK410DQMeFb1W9CW1EGfzlqc0y7mmZVm+IO57hI8zb4 Hn6RyBFqshkB6lLsIbh4IDVJMchInPOAZfvZb+NZEwtfawNeWu/9uuTJuJvhyCg3iRzd bpOnMiuV3smpxW36XDOu+Q+uEbqt40MzSV0y5JZYZhFTxpGSmEezxZf1B/HELspyxkJV rGGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716725701; x=1717330501; h=mime-version:user-agent:content-transfer-encoding:date:cc:to:from :subject:message-id:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=LABB0j8CIFdPWnuU0WFLYqhxIxkTz9JgVM44A/J5thE=; b=D6uQ5Ymn01+RdFeq8GqY+q1H5Akx60QCR1Yyh7Bd5fTtOlcPBw0TP3jOPof0VNj15q HXIZSxWbJoJRfBFM9y7bzY2ldLlp3Q4/j2h4lrsyWKEsVgtTkX02zZCCuKoLlCuggFGG pgIUOO6ZeEV686/6m0wHkloXBLfU6d7rh+PJfLKvaE8y76D8Z8FYJTKHoMUFtNdjkzXF Mn5n2tybVdQDPz0flx9Py/nsIBykUF3rbSWiYJYgdULRXAFLtrOardigfElMGEoS8ZXe 9l0o+MLNFdySi5g8f727uosKccKXhLHzt9IWUQst6g0ef0Dyc4rk6pIqfG+tFCxWSP6X 91mg== X-Gm-Message-State: AOJu0YxfyyNCaYkujKREAUNLBrR5DXFST+X5clKwD2+S6CbHYS3gff/X aAmIBbbPToNxar4rDSqelZ5yzef7xa1fxpb0RdSltO7WJsNUQ2ELfDSBgw== X-Google-Smtp-Source: AGHT+IHC8GV/NaY8HM2GcKzbXRLweoqjqqy9+Y+pcgcth7JtflviSruPYt0hwvvYA9Ug0eUBnsnArA== X-Received: by 2002:a5d:4d85:0:b0:354:ed11:a20a with SMTP id ffacd0b85a97d-354f75a0adbmr9177622f8f.29.1716725700402; Sun, 26 May 2024 05:15:00 -0700 (PDT) Received: from 2a02-8388-e203-9700-eddb-fb4f-5189-911d.cable.dynamic.v6.surfer.at (2a02-8388-e203-9700-eddb-fb4f-5189-911d.cable.dynamic.v6.surfer.at. [2a02:8388:e203:9700:eddb:fb4f:5189:911d]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-421089cca86sm75756115e9.42.2024.05.26.05.14.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 May 2024 05:15:00 -0700 (PDT) Message-ID: <8537ccea1c18dafc9d64b404b48d87c0f98eb2d6.camel@gmail.com> Subject: [C23 PATCH]: allow aliasing for types derived from structs with variable size From: Martin Uecker To: gcc-patches@gcc.gnu.org Cc: Joseph Myers , Richard Biener , Jakub Jelinek Date: Sun, 26 May 2024 14:14:58 +0200 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.46.4-2 MIME-Version: 1.0 X-Spam-Status: No, score=-8.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This is similar to the enum issue, where setting the alias set to zero is insufficient because also derived types need to be able to alias. After this change, it is also possible to add checking assertions that verify TYPE_CANONICAL for all tagged types at end of each call to the comptypes family. At least for the test suite this then shows no additional issues for tagged types. =C2=A0 (We still make incorrect aliasing decisions at least for types derived=C2= =A0 from=C2=A0 functions types (PR114959) but this is an ancient issue. We probably should set TYPE_CANONICAL in the FE similar to what is done for tagged types in C23.) Bootstrapped and regression tested on x86_64. C23: allow aliasing for types derived from structs with variable size =20 Previously, we set the aliasing set of structures with variable size =20 struct foo { int x[n]; char b; }; =20 to zero. The reason is that such types can be compatible to diffrent structure types which are incompatible. =20 struct foo { int x[2]; char b; }; struct foo { int x[3]; char b; }; =20 But it is not enough to set the aliasing set to zero, because derived types would then still end up in different equivalence classes even though they might be compatible. Instead those types should be set to structural equivalency. We also add checking assertions that ensure that TYPE_CANONICAL is set correctly for all tagged types =20 gcc/c/ * c-decl.cc (finish_struct): Do not set TYPE_CANONICAL for structure or unions with variable size. * c-objc-common.cc (c_get_alias_set): Do not set alias set to z= ero. * c-typeck.cc (comptypes_verify): New function. (comptypes,comptypes_same_p,comptypes_check_enum_int): Add asse= rtion. (comptypes_equiv_p): Add assertion that ensures that compatible types have the same equivalence class. (tagged_types_tu_compatible_p): Remove now unneeded special cas= e. =20 gcc/testsuite/ * gcc.dg/gnu23-tag-alias-8.c: New test. diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 6e6606c9570..9f7d55c0b10 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -9749,7 +9749,7 @@ finish_struct (location_t loc, tree t, tree fieldlist= , tree attributes, C_TYPE_BEING_DEFINED (t) =3D 0; =20 /* Set type canonical based on equivalence class. */ - if (flag_isoc23) + if (flag_isoc23 && !C_TYPE_VARIABLE_SIZE (t)) { if (c_struct_htab =3D=3D NULL) c_struct_htab =3D hash_table::create_ggc (61); diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc index 551ec6f4b65..29127d037e1 100644 --- a/gcc/c/c-objc-common.cc +++ b/gcc/c/c-objc-common.cc @@ -420,11 +420,6 @@ c_var_mod_p (tree x, tree fn ATTRIBUTE_UNUSED) alias_set_type c_get_alias_set (tree t) { - /* Structs with variable size can alias different incompatible - structs. Let them alias anything. */ - if (RECORD_OR_UNION_TYPE_P (t) && C_TYPE_VARIABLE_SIZE (t)) - return 0; - return c_common_get_alias_set (t); } =20 diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 2d092357e0f..c07e2f2b5cf 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -1167,6 +1167,28 @@ common_type (tree t1, tree t2) return c_common_type (t1, t2); } =20 + + +/* Helper function for comptypes. For two compatible types, return 1 + if they pass consistency checks. In particular we test that + TYPE_CANONICAL ist set correctly, i.e. the two types can alias. */ + +static bool +comptypes_verify (tree type1, tree type2) +{ + if (TYPE_CANONICAL (type1) !=3D TYPE_CANONICAL (type2) + && !TYPE_STRUCTURAL_EQUALITY_P (type1) + && !TYPE_STRUCTURAL_EQUALITY_P (type2)) + { + /* FIXME: check other types. */ + if (RECORD_OR_UNION_TYPE_P (type1) + || TREE_CODE (type1) =3D=3D ENUMERAL_TYPE + || TREE_CODE (type2) =3D=3D ENUMERAL_TYPE) + return false; + } + return true; +} + struct comptypes_data { bool enum_and_int_p; bool different_types_p; @@ -1187,6 +1209,8 @@ comptypes (tree type1, tree type2) struct comptypes_data data =3D { }; bool ret =3D comptypes_internal (type1, type2, &data); =20 + gcc_checking_assert (!ret || comptypes_verify (type1, type2)); + return ret ? (data.warning_needed ? 2 : 1) : 0; } =20 @@ -1200,6 +1224,8 @@ comptypes_same_p (tree type1, tree type2) struct comptypes_data data =3D { }; bool ret =3D comptypes_internal (type1, type2, &data); =20 + gcc_checking_assert (!ret || comptypes_verify (type1, type2)); + if (data.different_types_p) return false; =20 @@ -1217,6 +1243,8 @@ comptypes_check_enum_int (tree type1, tree type2, boo= l *enum_and_int_p) bool ret =3D comptypes_internal (type1, type2, &data); *enum_and_int_p =3D data.enum_and_int_p; =20 + gcc_checking_assert (!ret || comptypes_verify (type1, type2)); + return ret ? (data.warning_needed ? 2 : 1) : 0; } =20 @@ -1231,6 +1259,8 @@ comptypes_check_different_types (tree type1, tree typ= e2, bool ret =3D comptypes_internal (type1, type2, &data); *different_types_p =3D data.different_types_p; =20 + gcc_checking_assert (!ret || comptypes_verify (type1, type2)); + return ret ? (data.warning_needed ? 2 : 1) : 0; } =20 @@ -1245,6 +1275,10 @@ comptypes_equiv_p (tree type1, tree type2) data.equiv =3D true; bool ret =3D comptypes_internal (type1, type2, &data); =20 + /* check that different equivance classes are assigned only + to types that are not compatible. */ + gcc_checking_assert (ret || !comptypes (type1, type2)); + return ret; } =20 @@ -1593,9 +1627,6 @@ tagged_types_tu_compatible_p (const_tree t1, const_tr= ee t2, if (list_length (TYPE_FIELDS (t1)) !=3D list_length (TYPE_FIELDS (t2))) return false; =20 - if (data->equiv && (C_TYPE_VARIABLE_SIZE (t1) || C_TYPE_VARIABLE_SIZE (t2= ))) - return false; - for (s1 =3D TYPE_FIELDS (t1), s2 =3D TYPE_FIELDS (t2); s1 && s2; s1 =3D DECL_CHAIN (s1), s2 =3D DECL_CHAIN (s2)) diff --git a/gcc/testsuite/gcc.dg/gnu23-tag-alias-8.c b/gcc/testsuite/gcc.d= g/gnu23-tag-alias-8.c new file mode 100644 index 00000000000..11f2787521e --- /dev/null +++ b/gcc/testsuite/gcc.dg/gnu23-tag-alias-8.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-std=3Dgnu23 -O2" } */ + +typedef struct E { int a[2]; int b; } *A; + +void* foo(void* a, void *b, void *c, void *d) +{ + *(A**)a =3D c; + + int N =3D 2; + typedef struct E { int a[N]; int b; } *B; + *(B**)b =3D d; + + return *(A**)a; +} + +int main() +{ + A *a, b, c; + if (&c !=3D (A*)foo(&a, &a, &b, &c)) + __builtin_abort(); +} + +