From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 063223858288 for ; Thu, 10 Aug 2023 15:38:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 063223858288 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691681900; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references; bh=Hw86/R2oXJ1/vNckvysiq8kYOwVw7wBRcW9iNcbjeKE=; b=fss/EoyGjNpCTjzuOELqwo4eJekfW3+oR/KRIurtwFqz/mdav1e5352MpXIcZu6iy2nGG+ BGdJXh0lIkNigAA5q2eAfaiofVSt3DptpLar8dmg+tHkK42JIaSxppdUgff84hRZk3vDJB 2elxpcQTS8pRtXv0Nsmpwjc6HFVPsSs= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-590-WYfrfNViMeeCxghCpFDhLw-1; Thu, 10 Aug 2023 11:38:19 -0400 X-MC-Unique: WYfrfNViMeeCxghCpFDhLw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 247C4800CA6; Thu, 10 Aug 2023 15:38:19 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.225.169]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D5A022166B25; Thu, 10 Aug 2023 15:38:18 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 37AFcGAI2356874 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 10 Aug 2023 17:38:16 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 37AFcFka2356873; Thu, 10 Aug 2023 17:38:15 +0200 Date: Thu, 10 Aug 2023 17:38:15 +0200 From: Jakub Jelinek To: "Joseph S. Myers" , Marek Polacek , gcc-patches@gcc.gnu.org Subject: [PATCH] c, v2: Add stdckdint.h header for C23 Message-ID: Reply-To: Jakub Jelinek References: MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,KAM_NUMSUBJECT,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi! Here is an updated version of the stdckdint.h patch. It is dependent on the 2 patches I've just sent. Compared to the June version of the patch, this one will #include_next if possible the same header from the C library, so that the responsibility to maintain it can be shared between the compiler and C library. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? On Mon, Jun 12, 2023 at 09:59:34PM +0200, Jakub Jelinek via Gcc-patches wrote: > The following patch is an updated version of the patch I've posted > on Saturday, on top of the 2 patches I've posted a few minutes ago. 2023-08-10 Jakub Jelinek * Makefile.in (USER_H): Add stdckdint.h. * ginclude/stdckdint.h: New file. * gcc.dg/stdckdint-1.c: New test. * gcc.dg/stdckdint-2.c: New test. --- gcc/Makefile.in.jj 2023-06-06 20:02:35.581211930 +0200 +++ gcc/Makefile.in 2023-06-10 10:17:05.062270115 +0200 @@ -466,6 +466,7 @@ USER_H = $(srcdir)/ginclude/float.h \ $(srcdir)/ginclude/stdnoreturn.h \ $(srcdir)/ginclude/stdalign.h \ $(srcdir)/ginclude/stdatomic.h \ + $(srcdir)/ginclude/stdckdint.h \ $(EXTRA_HEADERS) USER_H_INC_NEXT_PRE = @user_headers_inc_next_pre@ --- gcc/ginclude/stdckdint.h.jj 2023-08-10 13:01:31.557989195 +0200 +++ gcc/ginclude/stdckdint.h 2023-08-10 13:11:51.095109866 +0200 @@ -0,0 +1,63 @@ +/* Copyright (C) 2023 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* ISO C23: 7.20 Checked Integer Arithmetic . */ + +#ifndef _STDCKDINT_H +#define _STDCKDINT_H + +#define __STDC_VERSION_STDCKDINT_H__ 202311L + +#if __STDC_VERSION__ >= 201112L +# define __ckd_type_check_1(a, n) \ + _Static_assert (_Generic (((__typeof_unqual__ (a)) 0), \ + char: 0, \ + default: __builtin_classify_type (__typeof__ (a)) \ + == 1), \ + "types used in " n " should be integral other than plain " \ + "char, bool, bit-precise integer or enumerated type") +# define __ckd_type_check(r, a, b, n) \ + (__extension__ ({ __ckd_type_check_1 ((r)[0], n); \ + __ckd_type_check_1 (a, n); \ + __ckd_type_check_1 (b, n); \ + (r); })) +#else +# define __ckd_type_check(r, a, b, n) r +#endif + +#define ckd_add(r, a, b) \ + ((_Bool) __builtin_add_overflow (a, b, \ + __ckd_type_check (r, a, b, "ckd_add"))) +#define ckd_sub(r, a, b) \ + ((_Bool) __builtin_sub_overflow (a, b, \ + __ckd_type_check (r, a, b, "ckd_sub"))) +#define ckd_mul(r, a, b) \ + ((_Bool) __builtin_mul_overflow (a, b, \ + __ckd_type_check (r, a, b, "ckd_mul"))) + +/* Allow for the C library to add its part to the header. */ +#if __has_include_next () +# include_next +#endif + +#endif /* stdckdint.h */ --- gcc/testsuite/gcc.dg/stdckdint-1.c.jj 2023-06-10 10:04:23.547792318 +0200 +++ gcc/testsuite/gcc.dg/stdckdint-1.c 2023-06-10 10:50:29.748579415 +0200 @@ -0,0 +1,61 @@ +/* Test C23 Checked Integer Arithmetic macros in . */ +/* { dg-do run } */ +/* { dg-options "-std=c2x" } */ + +#include + +#if __STDC_VERSION_STDCKDINT_H__ != 202311L +# error __STDC_VERSION_STDCKDINT_H__ not defined to 202311L +#endif + +extern void abort (void); + +int +main () +{ + unsigned int a; + if (ckd_add (&a, 1, 2) || a != 3) + abort (); + if (ckd_add (&a, ~2U, 2) || a != ~0U) + abort (); + if (!ckd_add (&a, ~2U, 4) || a != 1) + abort (); + if (ckd_sub (&a, 42, 2) || a != 40) + abort (); + if (!ckd_sub (&a, 11, ~0ULL) || a != 12) + abort (); + if (ckd_mul (&a, 42, 16U) || a != 672) + abort (); + if (ckd_mul (&a, ~0UL, 0) || a != 0) + abort (); + if (ckd_mul (&a, 1, ~0U) || a != ~0U) + abort (); + if (ckd_mul (&a, ~0UL, 1) != (~0UL > ~0U) || a != ~0U) + abort (); + static_assert (_Generic (ckd_add (&a, 1, 1), bool: 1, default: 0)); + static_assert (_Generic (ckd_sub (&a, 1, 1), bool: 1, default: 0)); + static_assert (_Generic (ckd_mul (&a, 1, 1), bool: 1, default: 0)); + signed char b; + if (ckd_add (&b, 8, 12) || b != 20) + abort (); + if (ckd_sub (&b, 8UL, 12ULL) || b != -4) + abort (); + if (ckd_mul (&b, 2, 3) || b != 6) + abort (); + unsigned char c; + if (ckd_add (&c, 8, 12) || c != 20) + abort (); + if (ckd_sub (&c, 8UL, 12ULL) != (-4ULL > (unsigned char) -4U) + || c != (unsigned char) -4U) + abort (); + if (ckd_mul (&c, 2, 3) || c != 6) + abort (); + long long d; + if (ckd_add (&d, ~0U, ~0U) != (~0U + 1ULL < ~0U) + || d != (long long) (2 * (unsigned long long) ~0U)) + abort (); + if (ckd_sub (&d, 0, 0) || d != 0) + abort (); + if (ckd_mul (&d, 16, 1) || d != 16) + abort (); +} --- gcc/testsuite/gcc.dg/stdckdint-2.c.jj 2023-06-10 10:04:31.600681050 +0200 +++ gcc/testsuite/gcc.dg/stdckdint-2.c 2023-06-12 18:10:23.201127813 +0200 @@ -0,0 +1,53 @@ +/* Test C23 Checked Integer Arithmetic macros in . */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x" } */ + +#include + +int +main () +{ + char a; + bool b; + enum E { E1, E2 } c = E1; + int d; + ckd_add (&a, 1, 1); /* { dg-error "types used in ckd_add should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_sub (&a, 1, 1); /* { dg-error "types used in ckd_sub should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_mul (&a, 1, 1); /* { dg-error "types used in ckd_mul should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_add (&b, 1, 1); /* { dg-error "types used in ckd_add should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + /* { dg-error "has pointer to boolean type" "" { target *-*-* } .-1 } */ + ckd_sub (&b, 1, 1); /* { dg-error "types used in ckd_sub should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + /* { dg-error "has pointer to boolean type" "" { target *-*-* } .-1 } */ + ckd_mul (&b, 1, 1); /* { dg-error "types used in ckd_mul should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + /* { dg-error "has pointer to boolean type" "" { target *-*-* } .-1 } */ + ckd_add (&c, 1, 1); /* { dg-error "types used in ckd_add should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + /* { dg-error "has pointer to enumerated type" "" { target *-*-* } .-1 } */ + ckd_sub (&c, 1, 1); /* { dg-error "types used in ckd_sub should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + /* { dg-error "has pointer to enumerated type" "" { target *-*-* } .-1 } */ + ckd_mul (&c, 1, 1); /* { dg-error "types used in ckd_mul should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + /* { dg-error "has pointer to enumerated type" "" { target *-*-* } .-1 } */ + ckd_add (&d, (char) 1, 1); /* { dg-error "types used in ckd_add should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_sub (&d, (char) 1, 1); /* { dg-error "types used in ckd_sub should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_mul (&d, (char) 1, 1); /* { dg-error "types used in ckd_mul should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_add (&d, false, 1); /* { dg-error "types used in ckd_add should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_sub (&d, false, 1); /* { dg-error "types used in ckd_sub should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_mul (&d, false, 1); /* { dg-error "types used in ckd_mul should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_add (&d, true, 1); /* { dg-error "types used in ckd_add should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_sub (&d, true, 1); /* { dg-error "types used in ckd_sub should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_mul (&d, true, 1); /* { dg-error "types used in ckd_mul should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_add (&d, c, 1); /* { dg-error "types used in ckd_add should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_sub (&d, c, 1); /* { dg-error "types used in ckd_sub should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_mul (&d, c, 1); /* { dg-error "types used in ckd_mul should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_add (&d, 1, (char) 1); /* { dg-error "types used in ckd_add should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_sub (&d, 1, (char) 1); /* { dg-error "types used in ckd_sub should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_mul (&d, 1, (char) 1); /* { dg-error "types used in ckd_mul should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_add (&d, 1, false); /* { dg-error "types used in ckd_add should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_sub (&d, 1, false); /* { dg-error "types used in ckd_sub should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_mul (&d, 1, false); /* { dg-error "types used in ckd_mul should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_add (&d, 1, true); /* { dg-error "types used in ckd_add should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_sub (&d, 1, true); /* { dg-error "types used in ckd_sub should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_mul (&d, 1, true); /* { dg-error "types used in ckd_mul should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_add (&d, 1, c); /* { dg-error "types used in ckd_add should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_sub (&d, 1, c); /* { dg-error "types used in ckd_sub should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ + ckd_mul (&d, 1, c); /* { dg-error "types used in ckd_mul should be integral other than plain char, bool, bit-precise integer or enumerated type" } */ +} Jakub