aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libc/config/linux/aarch64/headers.txt1
-rw-r--r--libc/config/linux/arm/headers.txt1
-rw-r--r--libc/config/linux/riscv/headers.txt1
-rw-r--r--libc/config/linux/x86_64/headers.txt1
-rw-r--r--libc/docs/c23.rst3
-rw-r--r--libc/include/CMakeLists.txt9
-rw-r--r--libc/include/llvm-libc-macros/CMakeLists.txt6
-rw-r--r--libc/include/llvm-libc-macros/stdckdint-macros.h25
-rw-r--r--libc/include/stdckdint.h.def18
-rw-r--r--libc/spec/stdc.td14
-rw-r--r--libc/src/stdckdint/CMakeLists.txt0
-rw-r--r--libc/test/include/CMakeLists.txt10
-rw-r--r--libc/test/include/stdckdint_test.cpp32
13 files changed, 120 insertions, 1 deletions
diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt
index 1725f9c..21b880c 100644
--- a/libc/config/linux/aarch64/headers.txt
+++ b/libc/config/linux/aarch64/headers.txt
@@ -10,6 +10,7 @@ set(TARGET_PUBLIC_HEADERS
libc.include.math
libc.include.pthread
libc.include.signal
+ libc.include.stdckdint
libc.include.stdbit
libc.include.stdio
libc.include.stdlib
diff --git a/libc/config/linux/arm/headers.txt b/libc/config/linux/arm/headers.txt
index c482371..268c8c4 100644
--- a/libc/config/linux/arm/headers.txt
+++ b/libc/config/linux/arm/headers.txt
@@ -5,6 +5,7 @@ set(TARGET_PUBLIC_HEADERS
libc.include.float
libc.include.inttypes
libc.include.math
+ libc.include.stdckdint
libc.include.stdbit
libc.include.stdlib
libc.include.string
diff --git a/libc/config/linux/riscv/headers.txt b/libc/config/linux/riscv/headers.txt
index 5e8af22..3ebea2e 100644
--- a/libc/config/linux/riscv/headers.txt
+++ b/libc/config/linux/riscv/headers.txt
@@ -15,6 +15,7 @@ set(TARGET_PUBLIC_HEADERS
libc.include.signal
libc.include.spawn
libc.include.setjmp
+ libc.include.stdckdint
libc.include.stdbit
libc.include.stdio
libc.include.stdlib
diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt
index d0c662c..a887eba 100644
--- a/libc/config/linux/x86_64/headers.txt
+++ b/libc/config/linux/x86_64/headers.txt
@@ -15,6 +15,7 @@ set(TARGET_PUBLIC_HEADERS
libc.include.signal
libc.include.spawn
libc.include.setjmp
+ libc.include.stdckdint
libc.include.stdbit
libc.include.stdfix
libc.include.stdio
diff --git a/libc/docs/c23.rst b/libc/docs/c23.rst
index 6d5edbf..ec9d409 100644
--- a/libc/docs/c23.rst
+++ b/libc/docs/c23.rst
@@ -4,6 +4,7 @@
C23 Support
===========
+.. include:: check.rst
.. contents:: Table of Contents
:depth: 4
:local:
@@ -17,7 +18,7 @@ Implementation Status
New headers:
* stdbit.h
-* stdckdint.h
+* stdckdint.h (|check|, macros are only defined with `__GNUC__` builtins)
Additions:
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 5882d03..dc3c9b8 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -243,6 +243,15 @@ add_gen_header(
)
add_gen_header(
+ stdckdint
+ DEF_FILE stdckdint.h.def
+ GEN_HDR stdckdint.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-macros.stdckdint_macros
+)
+
+add_gen_header(
stdio
DEF_FILE stdio.h.def
GEN_HDR stdio.h
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index 225885d..6e087582 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -233,3 +233,9 @@ add_macro_header(
HDR
stdfix-macros.h
)
+
+add_macro_header(
+ stdckdint_macros
+ HDR
+ stdckdint-macros.h
+)
diff --git a/libc/include/llvm-libc-macros/stdckdint-macros.h b/libc/include/llvm-libc-macros/stdckdint-macros.h
new file mode 100644
index 0000000..03b73ae
--- /dev/null
+++ b/libc/include/llvm-libc-macros/stdckdint-macros.h
@@ -0,0 +1,25 @@
+//===-- Definition of macros for stdckdint.h ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LLVM_LIBC_MACROS_STDCKDINT_MACROS_H
+#define __LLVM_LIBC_MACROS_STDCKDINT_MACROS_H
+
+// We need to use __builtin_*_overflow from GCC/Clang to implement the overflow
+// macros. Check __GNUC__ for availability of such builtins.
+#ifdef __GNUC__
+// clang/gcc overlay may provides similar macros, we need to avoid redefining
+// them.
+#ifndef __STDC_VERSION_STDCKDINT_H__
+#define __STDC_VERSION_STDCKDINT_H__ 202311L
+
+#define ckd_add(R, A, B) __builtin_add_overflow((A), (B), (R))
+#define ckd_sub(R, A, B) __builtin_sub_overflow((A), (B), (R))
+#define ckd_mul(R, A, B) __builtin_mul_overflow((A), (B), (R))
+#endif // __STDC_VERSION_STDCKDINT_H__
+#endif // __GNUC__
+#endif // __LLVM_LIBC_MACROS_STDCKDINT_MACROS_H
diff --git a/libc/include/stdckdint.h.def b/libc/include/stdckdint.h.def
new file mode 100644
index 0000000..c824709
--- /dev/null
+++ b/libc/include/stdckdint.h.def
@@ -0,0 +1,18 @@
+//===-- C standard library header stdckdint.h -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_STDCKDINT_H
+#define LLVM_LIBC_STDCKDINT_H
+
+#include <__llvm-libc-common.h>
+
+%%public_api()
+
+#include <llvm-libc-macros/stdckdint-macros.h>
+
+#endif // LLVM_LIBC_STDCKDINT_H
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 5fdcec7..3fe19fa 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -833,6 +833,19 @@ def StdC : StandardSpec<"stdc"> {
] // Functions
>;
+ HeaderSpec StdCkdInt = HeaderSpec<
+ "stdckdint.h",
+ [
+ Macro<"__STDC_VERSION_STDCKDINT_H__">,
+ Macro<"ckd_add">,
+ Macro<"ckd_sub">,
+ Macro<"ckd_mul">
+ ], // Macros
+ [], // Types
+ [], // Enumerations
+ [] // Functions
+ >;
+
HeaderSpec StdLib = HeaderSpec<
"stdlib.h",
[], // Macros
@@ -1234,6 +1247,7 @@ def StdC : StandardSpec<"stdc"> {
Math,
String,
StdBit,
+ StdCkdInt,
StdIO,
StdLib,
IntTypes,
diff --git a/libc/src/stdckdint/CMakeLists.txt b/libc/src/stdckdint/CMakeLists.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libc/src/stdckdint/CMakeLists.txt
diff --git a/libc/test/include/CMakeLists.txt b/libc/test/include/CMakeLists.txt
index 2730fa0..bf845c94 100644
--- a/libc/test/include/CMakeLists.txt
+++ b/libc/test/include/CMakeLists.txt
@@ -33,3 +33,13 @@ if(LLVM_LIBC_FULL_BUILD AND libc.include.stdbit IN_LIST TARGET_PUBLIC_HEADERS)
# to.
)
endif()
+
+add_libc_test(
+ stdckdint_test
+ SUITE
+ libc_include_tests
+ SRCS
+ stdckdint_test.cpp
+ DEPENDS
+ libc.include.llvm-libc-macros.stdckdint_macros
+)
diff --git a/libc/test/include/stdckdint_test.cpp b/libc/test/include/stdckdint_test.cpp
new file mode 100644
index 0000000..1180a6d
--- /dev/null
+++ b/libc/test/include/stdckdint_test.cpp
@@ -0,0 +1,32 @@
+//===-- Unittests for stdckdint -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "test/UnitTest/Test.h"
+
+#include "include/llvm-libc-macros/stdckdint-macros.h"
+
+TEST(LlvmLibcStdCkdIntTest, Add) {
+ int result;
+ ASSERT_FALSE(ckd_add(&result, 1, 2));
+ ASSERT_EQ(result, 3);
+ ASSERT_TRUE(ckd_add(&result, INT_MAX, 1));
+}
+
+TEST(LlvmLibcStdCkdIntTest, Sub) {
+ int result;
+ ASSERT_FALSE(ckd_sub(&result, 3, 2));
+ ASSERT_EQ(result, 1);
+ ASSERT_TRUE(ckd_sub(&result, INT_MIN, 1));
+}
+
+TEST(LlvmLibcStdCkdIntTest, Mul) {
+ int result;
+ ASSERT_FALSE(ckd_mul(&result, 2, 3));
+ ASSERT_EQ(result, 6);
+ ASSERT_TRUE(ckd_mul(&result, INT_MAX, 2));
+}