Skip to content

Commit 89b85c2

Browse files
committed
use of stdckdint.h
C23 is going to have this header. The industry is already moving towards accepting it; OSes and compilers started to implement theirs. Why not detect its presence and if any, prefer over other ways. See also: - https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2683.pdf - https://reviews.freebsd.org/D41734 - https://reviews.llvm.org/D157331 - https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=8441841a1b985d68245954af1ff023db121b0635
1 parent 67dd9af commit 89b85c2

File tree

5 files changed

+82
-3
lines changed

5 files changed

+82
-3
lines changed

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,6 +1367,7 @@ AC_CHECK_HEADERS(ucontext.h)
13671367
AC_CHECK_HEADERS(utime.h)
13681368
AC_CHECK_HEADERS(sys/epoll.h)
13691369
AC_CHECK_HEADERS(sys/event.h)
1370+
AC_CHECK_HEADERS(stdckdint.h)
13701371

13711372
AS_CASE("$target_cpu", [x64|x86_64|i[3-6]86*], [
13721373
AC_CHECK_HEADERS(x86intrin.h)

gc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,9 @@ size_add_overflow(size_t x, size_t y)
224224
bool p;
225225
#if 0
226226

227+
#elif defined(ckd_add)
228+
p = ckd_add(&z, x, y);
229+
227230
#elif __has_builtin(__builtin_add_overflow)
228231
p = __builtin_add_overflow(x, y, &z);
229232

hrtime.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
# include <sys/time.h>
77
#endif
88

9+
#include "internal/compilers.h"
10+
911
/*
1012
* Hi-res monotonic clock. It is currently nsec resolution, which has over
1113
* 500 years of range (with an unsigned 64-bit integer). Developers
@@ -61,7 +63,11 @@ rb_hrtime_mul(rb_hrtime_t a, rb_hrtime_t b)
6163
{
6264
rb_hrtime_t c;
6365

64-
#ifdef HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW
66+
#ifdef ckd_mul
67+
if (ckd_mul(&c, a, b))
68+
return RB_HRTIME_MAX;
69+
70+
#elif __has_builtin(__builtin_mul_overflow)
6571
if (__builtin_mul_overflow(a, b, &c))
6672
return RB_HRTIME_MAX;
6773
#else
@@ -81,7 +87,11 @@ rb_hrtime_add(rb_hrtime_t a, rb_hrtime_t b)
8187
{
8288
rb_hrtime_t c;
8389

84-
#ifdef HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW
90+
#ifdef ckd_add
91+
if (ckd_add(&c, a, b))
92+
return RB_HRTIME_MAX;
93+
94+
#elif __has_builtin(__builtin_add_overflow)
8595
if (__builtin_add_overflow(a, b, &c))
8696
return RB_HRTIME_MAX;
8797
#else

include/ruby/internal/memory.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include "ruby/internal/has/builtin.h"
5757
#include "ruby/internal/stdalign.h"
5858
#include "ruby/internal/stdbool.h"
59+
#include "ruby/internal/stdckdint.h"
5960
#include "ruby/internal/xmalloc.h"
6061
#include "ruby/backward/2/limits.h"
6162
#include "ruby/backward/2/long_long.h"
@@ -567,7 +568,10 @@ rbimpl_size_mul_overflow(size_t x, size_t y)
567568
{
568569
struct rbimpl_size_mul_overflow_tag ret = { false, 0, };
569570

570-
#if RBIMPL_HAS_BUILTIN(__builtin_mul_overflow)
571+
#if defined(ckd_mul)
572+
ret.left = ckd_mul(&ret.right, x, y);
573+
574+
#elif RBIMPL_HAS_BUILTIN(__builtin_mul_overflow)
571575
ret.left = __builtin_mul_overflow(x, y, &ret.right);
572576

573577
#elif defined(DSIZE_T)

include/ruby/internal/stdckdint.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#ifndef RBIMPL_STDCKDINT_H /*-*-C++-*-vi:se ft=cpp:*/
2+
#define RBIMPL_STDCKDINT_H
3+
/**
4+
* @author Ruby developers <ruby-core@ruby-lang.org>
5+
* @copyright This file is a part of the programming language Ruby.
6+
* Permission is hereby granted, to either redistribute and/or
7+
* modify this file, provided that the conditions mentioned in the
8+
* file COPYING are met. Consult the file for details.
9+
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
10+
* implementation details. Don't take them as canon. They could
11+
* rapidly appear then vanish. The name (path) of this header file
12+
* is also an implementation detail. Do not expect it to persist
13+
* at the place it is now. Developers are free to move it anywhere
14+
* anytime at will.
15+
* @note To ruby-core: remember that this header can be possibly
16+
* recursively included from extension libraries written in C++.
17+
* Do not expect for instance `__VA_ARGS__` is always available.
18+
* We assume C99 for ruby itself but we don't assume languages of
19+
* extension libraries. They could be written in C++98.
20+
* @brief C23 shim for <stdckdint.h>
21+
*/
22+
#include "ruby/internal/config.h"
23+
#include "ruby/internal/has/builtin.h"
24+
#include "ruby/internal/stdbool.h"
25+
26+
#ifdef __has_include
27+
# if __has_include(<stdckdint.h>)
28+
# /* Conforming C23 situation; e.g. recent clang */
29+
# define RBIMPL_HAVE_STDCKDINT_H
30+
# endif
31+
#endif
32+
33+
#ifdef HAVE_STDCKDINT_H
34+
# /* Some OSes (most notably FreeBSD) have this file. */
35+
# define RBIMPL_HAVE_STDCKDINT_H
36+
#endif
37+
38+
#ifdef RBIMPL_HAVE_STDCKDINT_H
39+
# /* Take that. */
40+
# include <stdckdint.h>
41+
42+
#elif RBIMPL_HAS_BUILTIN(__builtin_add_overflow)
43+
# /* Compiler builtin; kind of ubiquitos these days */
44+
# define ckd_add(x, y, z) (bool)__builtin_add_overflow((y), (z), (x))
45+
# define ckd_sub(x, y, x) (bool)__builtin_sub_overflow((y), (z), (x))
46+
# define ckd_mul(x, y, x) (bool)__builtin_mul_overflow((y), (z), (x))
47+
# define __STDC_VERSION_STDCKDINT_H__ 202311L
48+
49+
#/* elif defined(__cplusplus) */
50+
#/* :TODO: if we assume C++11 we can use `<type_traits>` to implement them. */
51+
52+
#else
53+
# /* intentionally leave them undefined */
54+
# /* to make `#ifdef ckd_add` work as intended. */
55+
# undef ckd_add
56+
# undef ckd_sub
57+
# undef ckd_mul
58+
# undef __STDC_VERSION_STDCKDINT_H__
59+
#endif
60+
61+
#endif /* RBIMPL_STDCKDINT_H */

0 commit comments

Comments
 (0)