c, v3: Add stdckdint.h header for C23

Message ID ZNXstoaxDzI1OEwE@tucnak
State Unresolved
Headers
Series c, v3: Add stdckdint.h header for C23 |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Jakub Jelinek Aug. 11, 2023, 8:09 a.m. UTC
  On Thu, Aug 10, 2023 at 10:31:12PM +0000, Joseph Myers wrote:
> > The following patch (on top of the stdckdint.h patch and _BitInt patch
> > series) adds a test for _BitInt diagnostics of ckd_{add,sub,mul} macros.
> 
> I remain unconvinced that diagnosing use with types where it's clear what 
> the right semantics for the operation are is a good idea (given, in the 
> _BitInt case, that you've already implemented the built-in functions for 
> _BitInt types).  (Diagnosing for bool results *is* a good idea, since it's 
> not clear what the semantics should be.  Likewise for enums with fixed 
> underlying type bool, whether or not it's diagnosed for other enums.)

Ok, here is an updated patch without that diagnostics.
All that is diagnosed is when result is bool or enum (any kind).  Even for
enums without bool underlying type, a question is what exactly it would
mean, whether checking result fits into the range of the underlying type,
or range between smallest and largest enumerator, or signed/unsigned range
with minimum precision to represent smallest/largest enumerator, or only
where the result would fall into some enumerator, so I think punting on
those as we do for years for __builtin_*_overflow is ok.

2023-08-11  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.



	Jakub
  

Comments

Joseph Myers Aug. 11, 2023, 1:25 p.m. UTC | #1
On Fri, 11 Aug 2023, Jakub Jelinek wrote:

> All that is diagnosed is when result is bool or enum (any kind).  Even for

I'd suggest tests that other nonsense cases are diagnosed, such as 
floating-point or pointer arguments or results (hopefully such cases are 
already diagnosed and just need tests).
  

Patch

--- gcc/Makefile.in.jj	2023-08-10 17:23:55.502325592 +0200
+++ gcc/Makefile.in	2023-08-11 09:37:35.968944530 +0200
@@ -469,6 +469,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-11 09:37:35.968944530 +0200
+++ gcc/ginclude/stdckdint.h	2023-08-11 09:39:50.383054196 +0200
@@ -0,0 +1,40 @@ 
+/* 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
+
+#define ckd_add(r, a, b) ((_Bool) __builtin_add_overflow (a, b, r))
+#define ckd_sub(r, a, b) ((_Bool) __builtin_sub_overflow (a, b, r))
+#define ckd_mul(r, a, b) ((_Bool) __builtin_mul_overflow (a, b, r))
+
+/* Allow for the C library to add its part to the header.  */
+#if !defined (_LIBC_STDCKDINT_H) && __has_include_next (<stdckdint.h>)
+# include_next <stdckdint.h>
+#endif
+
+#endif /* stdckdint.h */
--- gcc/testsuite/gcc.dg/stdckdint-1.c.jj	2023-08-11 09:37:35.968944530 +0200
+++ gcc/testsuite/gcc.dg/stdckdint-1.c	2023-08-11 09:37:35.968944530 +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-08-11 09:37:35.968944530 +0200
+++ gcc/testsuite/gcc.dg/stdckdint-2.c	2023-08-11 09:56:58.536595283 +0200
@@ -0,0 +1,47 @@ 
+/* 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);
+  ckd_sub (&a, 1, 1);
+  ckd_mul (&a, 1, 1);
+  ckd_add (&b, 1, 1);		/* { dg-error "has pointer to boolean type" } */
+  ckd_sub (&b, 1, 1);		/* { dg-error "has pointer to boolean type" } */
+  ckd_mul (&b, 1, 1);		/* { dg-error "has pointer to boolean type" } */
+  ckd_add (&c, 1, 1);		/* { dg-error "has pointer to enumerated type" } */
+  ckd_sub (&c, 1, 1);		/* { dg-error "has pointer to enumerated type" } */
+  ckd_mul (&c, 1, 1);		/* { dg-error "has pointer to enumerated type" } */
+  ckd_add (&d, (char) 1, 1);
+  ckd_sub (&d, (char) 1, 1);
+  ckd_mul (&d, (char) 1, 1);
+  ckd_add (&d, false, 1);
+  ckd_sub (&d, false, 1);
+  ckd_mul (&d, false, 1);
+  ckd_add (&d, true, 1);
+  ckd_sub (&d, true, 1);
+  ckd_mul (&d, true, 1);
+  ckd_add (&d, c, 1);
+  ckd_sub (&d, c, 1);
+  ckd_mul (&d, c, 1);
+  ckd_add (&d, 1, (char) 1);
+  ckd_sub (&d, 1, (char) 1);
+  ckd_mul (&d, 1, (char) 1);
+  ckd_add (&d, 1, false);
+  ckd_sub (&d, 1, false);
+  ckd_mul (&d, 1, false);
+  ckd_add (&d, 1, true);
+  ckd_sub (&d, 1, true);
+  ckd_mul (&d, 1, true);
+  ckd_add (&d, 1, c);
+  ckd_sub (&d, 1, c);
+  ckd_mul (&d, 1, c);
+}