From patchwork Tue Apr 2 19:02:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Uecker X-Patchwork-Id: 87943 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 900A4385840E for ; Tue, 2 Apr 2024 19:03:00 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mailrelay.tugraz.at (mailrelay.tugraz.at [129.27.2.202]) by sourceware.org (Postfix) with ESMTPS id A18D43858D28 for ; Tue, 2 Apr 2024 19:02:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A18D43858D28 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=tugraz.at Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tugraz.at ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A18D43858D28 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=129.27.2.202 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712084551; cv=none; b=bKK7YUxYsESDRt+5h/TxvmT7WcjXyA69SaXRD5d+4cdPdt6WH0dO14IhUqI2GzBAjT6ndXQjbvVj53bycxxDOF6ej7hG1gH7iecjNIx4IkYaJQmvtGG5y7oRMMM8eA1uZMLW4f8rZMidJwm2xEpAcbeQU7Q22VEW9qLGANxm/o8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712084551; c=relaxed/simple; bh=ayrCiJfvaYjM3EDUdr2Uudf+48C7uRqVzJk57StLHOU=; h=DKIM-Signature:Message-ID:Subject:From:To:Date:MIME-Version; b=rmKv+U09eiAwPoBBapq+A9uYbGEwL1LoUq0KTqyUbV0UGmpvfl5JZW/z7gMdSnqeK7GE6orwANQnzgryowDNy53pOv4nFMNr/ZuqAJ6gezO59MEAgijF19Qz2Pt3Yo5M8AasECxqNiCY2zTohyzqFjGSrLHjAhwPrR63LEa29Q8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from vra-169-244.tugraz.at (vra-169-244.tugraz.at [129.27.169.244]) by mailrelay.tugraz.at (Postfix) with ESMTPSA id 4V8HLh3JT0z3xCn; Tue, 2 Apr 2024 21:02:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tugraz.at; s=mailrelay; t=1712084540; bh=DHPbbtHCuLlX3MhxN/wgoQm0yVdhPUbxCAieJ3vz2BM=; h=Subject:From:To:Cc:Date:In-Reply-To:References; b=Uz8Too3G3T6kBg07XI1o9Gz+d+ZMmrZZEATqGmt+n7MPYPV6YI1yKxuSis7jge+t+ AuExrSZvOPqGpckTbxrymcJuvSOyETUSQoCOwvNO8N/dUgE7xDxt+0AZzQRBzucVMu 1GNLiMotYL1Xe3vmvKNXKALtkwjB/WHNfiL5cRxQ= Message-ID: <0379aa34b5050780f99894b4040e416e3e95e851.camel@tugraz.at> Subject: [C PATCH] fix aliasing for structures/unions with incomplete types From: Martin Uecker To: gcc-patches@gcc.gnu.org Cc: Joseph Myers Date: Tue, 02 Apr 2024 21:02:20 +0200 In-Reply-To: <02a9b94e4d653b6f1b9f89a1b62187f46e871738.camel@tugraz.at> References: <02a9b94e4d653b6f1b9f89a1b62187f46e871738.camel@tugraz.at> User-Agent: Evolution 3.46.4-2 MIME-Version: 1.0 X-TUG-Backscatter-control: G/VXY7/6zeyuAY/PU2/0qw X-Spam-Scanner: SpamAssassin 3.003001 X-Spam-Score-relay: -1.9 X-Scanned-By: MIMEDefang 2.74 on 129.27.10.117 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org While fixing the other issue, I realized that the way the equivalence classes are computed for TYPE_CANONICAL did not take into account that completion of struct types also affectes compatibility of types that contain pointers to them. So the algorithm must be more conservative creating bigger equivalence classes. Bootstrapped and regession tested on x86_64 [C23]fix aliasing for structures/unions with incomplete types When incomplete structure/union types are completed later, compatibility of struct types that contain pointers to such types changes. When forming equivalence classes for TYPE_CANONICAL, we therefor need to be conservative and treat all structs with the same tag which are pointer targets as equivalent. gcc/c/ * c-typeck.cc (comptypes_internal): Add flag to track whether a struct is the target of a pointer. (tagged_types_tu_compatible): When forming equivalence classes, treat pointed-to structs as equivalent. gcc/testsuite/ * gcc.dg/c23-tag-incomplate-alias-1.c: New test. --- gcc/c/c-typeck.cc | 11 ++++++ .../gcc.dg/c23-tag-incomplete-alias-1.c | 34 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/c23-tag-incomplete-alias-1.c diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index ddeab1e2a8a..b86450580ad 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -1170,6 +1170,7 @@ struct comptypes_data { bool different_types_p; bool warning_needed; bool anon_field; + bool pointedto; bool equiv; const struct tagged_tu_seen_cache* cache; @@ -1355,6 +1356,7 @@ comptypes_internal (const_tree type1, const_tree type2, /* Do not remove mode information. */ if (TYPE_MODE (t1) != TYPE_MODE (t2)) return false; + data->pointedto = true; return comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2), data); case FUNCTION_TYPE: @@ -1513,6 +1515,14 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2, if (TYPE_NAME (t1) != TYPE_NAME (t2)) return false; + /* When forming equivalence classes for TYPE_CANONICAL in C23, we + have to treat structs with the same tag as equivalent, when they + are targets of pointers inside other structs. This is necessary + so that the relationship of types does not change when incomplete + types are completed. */ + if (data->equiv && data->pointedto) + return true; + if (!data->anon_field && NULL_TREE == TYPE_NAME (t1)) return false; @@ -1608,6 +1618,7 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2, return false; data->anon_field = !DECL_NAME (s1); + data->pointedto = false; data->cache = &entry; if (!comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2), data)) diff --git a/gcc/testsuite/gcc.dg/c23-tag-incomplete-alias-1.c b/gcc/testsuite/gcc.dg/c23-tag-incomplete-alias-1.c new file mode 100644 index 00000000000..7fb6a8513b2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c23-tag-incomplete-alias-1.c @@ -0,0 +1,34 @@ +/* { dg-do run } + * { dg-options "-std=c23 -O2" } */ + +[[gnu::noinline]] +void *alias(void *ap, void *b, void *x, void *y) +{ + struct foo { struct bar *f; } *a = ap; + struct bar { long x; }; + + a->f = x; + + { + struct bar; + struct foo { struct bar *f; }; + struct bar { long x; }; + + ((struct foo*)b)->f = y; + } + + + return a->f; +} + +int main() +{ + struct bar { long x; }; + struct foo { struct bar *f; } a; + struct bar x, y; + if (&y != alias(&a, &a, &x, &y)) + __builtin_abort(); + + return 0; +} +