From: Jakub Jelinek <jakub@redhat.com>
To: "Joseph S. Myers" <joseph@codesourcery.com>,
Marek Polacek <polacek@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: [PATCH] c: Add stdckdint.h header for C23
Date: Mon, 12 Jun 2023 21:59:34 +0200 [thread overview]
Message-ID: <ZId5JjzFMuybL4v5@tucnak> (raw)
Hi!
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.
Bootstrapped/regtested on x86_64-linux and i686-linux.
2023-06-12 Jakub Jelinek <jakub@redhat.com>
* 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-06-10 09:20:39.154053338 +0200
+++ gcc/ginclude/stdckdint.h 2023-06-12 18:09:06.429184992 +0200
@@ -0,0 +1,58 @@
+/* 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
+<http://www.gnu.org/licenses/>. */
+
+/* ISO C23: 7.20 Checked Integer Arithmetic <stdckdint.h>. */
+
+#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")))
+
+#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 <stdckdint.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x" } */
+
+#include <stdckdint.h>
+
+#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 <stdckdint.h>. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x" } */
+
+#include <stdckdint.h>
+
+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
next reply other threads:[~2023-06-12 19:59 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-12 19:59 Jakub Jelinek [this message]
2023-08-10 15:38 ` [PATCH] c, v2: " Jakub Jelinek
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=ZId5JjzFMuybL4v5@tucnak \
--to=jakub@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=joseph@codesourcery.com \
--cc=polacek@redhat.com \
/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).