diff options
Diffstat (limited to 'libc')
45 files changed, 412 insertions, 545 deletions
diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt index 14718e2..ae555a25 100644 --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -363,7 +363,7 @@ elseif(LLVM_LIBC_FULL_BUILD) message(FATAL_ERROR "${LIBC_CONFIG_PATH}/headers.txt file not found and fullbuild requested.") endif() -# Check exclude.txt that appends to LIBC_EXCLUDE_ENTRYPOINTS list +# Check exclude.txt that appends to TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS list if(EXISTS "${LIBC_CONFIG_PATH}/exclude.txt") include("${LIBC_CONFIG_PATH}/exclude.txt") endif() diff --git a/libc/config/linux/x86_64/exclude.txt b/libc/config/linux/x86_64/exclude.txt index 2c218b7..a068631 100644 --- a/libc/config/linux/x86_64/exclude.txt +++ b/libc/config/linux/x86_64/exclude.txt @@ -19,3 +19,11 @@ if(NOT has_sys_random) ) endif() endif() + +include(CheckSymbolExists) +check_symbol_exists(SYS_faccessat2 "sys/syscall.h" HAVE_SYS_FACCESSAT2) +if(NOT HAVE_SYS_FACCESSAT2) + list(APPEND TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS + libc.src.unistd.faccessat + ) +endif() diff --git a/libc/include/llvm-libc-types/__barrier_type.h b/libc/include/llvm-libc-types/__barrier_type.h index 5971261..5752f83 100644 --- a/libc/include/llvm-libc-types/__barrier_type.h +++ b/libc/include/llvm-libc-types/__barrier_type.h @@ -9,6 +9,8 @@ #ifndef LLVM_LIBC_TYPES__BARRIER_TYPE_H #define LLVM_LIBC_TYPES__BARRIER_TYPE_H +#include <stdbool.h> + typedef struct __attribute__((aligned(8 /* alignof (Barrier) */))) { unsigned expected; unsigned waiting; diff --git a/libc/include/llvm-libc-types/pthread_barrierattr_t.h b/libc/include/llvm-libc-types/pthread_barrierattr_t.h index 064be5b..b62fdc0 100644 --- a/libc/include/llvm-libc-types/pthread_barrierattr_t.h +++ b/libc/include/llvm-libc-types/pthread_barrierattr_t.h @@ -9,6 +9,8 @@ #ifndef LLVM_LIBC_TYPES_PTHREAD_BARRIERATTR_T_H #define LLVM_LIBC_TYPES_PTHREAD_BARRIERATTR_T_H +#include <stdbool.h> + typedef struct { bool pshared; } pthread_barrierattr_t; diff --git a/libc/include/locale.yaml b/libc/include/locale.yaml index 4566984..3c3998e 100644 --- a/libc/include/locale.yaml +++ b/libc/include/locale.yaml @@ -1,7 +1,7 @@ header: locale.h header_template: locale.h.def macros: - - macro_name: NULL + - macro_name: "NULL" macro_header: null-macro.h types: - type_name: locale_t diff --git a/libc/include/stdio.yaml b/libc/include/stdio.yaml index 394437b..c50b4ec 100644 --- a/libc/include/stdio.yaml +++ b/libc/include/stdio.yaml @@ -1,7 +1,7 @@ header: stdio.h header_template: stdio.h.def macros: - - macro_name: NULL + - macro_name: "NULL" macro_header: null-macro.h - macro_name: stdout macro_value: stdout diff --git a/libc/include/stdlib.yaml b/libc/include/stdlib.yaml index 3b2ff13..495eb7e 100644 --- a/libc/include/stdlib.yaml +++ b/libc/include/stdlib.yaml @@ -5,7 +5,7 @@ standards: merge_yaml_files: - stdlib-malloc.yaml macros: - - macro_name: NULL + - macro_name: "NULL" macro_header: null-macro.h types: - type_name: __atexithandler_t diff --git a/libc/include/string.yaml b/libc/include/string.yaml index 0bf297e..22010f4 100644 --- a/libc/include/string.yaml +++ b/libc/include/string.yaml @@ -2,7 +2,7 @@ header: string.h standards: - stdc macros: - - macro_name: NULL + - macro_name: "NULL" macro_header: null-macro.h types: - type_name: locale_t diff --git a/libc/include/time.yaml b/libc/include/time.yaml index 2f80242..88e50d1 100644 --- a/libc/include/time.yaml +++ b/libc/include/time.yaml @@ -1,7 +1,7 @@ header: time.h header_template: time.h.def macros: - - macro_name: NULL + - macro_name: "NULL" macro_header: null-macro.h types: - type_name: struct_timeval diff --git a/libc/include/wchar.yaml b/libc/include/wchar.yaml index b8a0a74..fb5b19b 100644 --- a/libc/include/wchar.yaml +++ b/libc/include/wchar.yaml @@ -1,11 +1,15 @@ header: wchar.h header_template: wchar.h.def macros: - - macro_name: NULL + - macro_name: "NULL" macro_header: null-macro.h types: - type_name: FILE - type_name: size_t + # TODO: Remove this once we have a function declaration using "struct tm" + # (wcsftime). We're declaring it here now, since libc++ expects + # forward-declaration of "struct tm" in the <wchar.h> header. + - type_name: struct_tm - type_name: wint_t - type_name: wchar_t - type_name: mbstate_t @@ -188,8 +192,8 @@ functions: standards: - stdc return_type: wchar_t * - arguments: - - type: wchar_t *__restrict + arguments: + - type: wchar_t *__restrict - type: const wchar_t *__restrict - type: size_t - name: wmemmove @@ -212,7 +216,7 @@ functions: standards: - stdc return_type: wchar_t * - arguments: + arguments: - type: wchar_t *__restrict - type: const wchar_t *__restrict - name: wcslcat diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt index 0ef09a9..b7af751 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -179,19 +179,7 @@ add_header_library( DEPENDS .ctype_utils .str_to_num_result - libc.hdr.errno_macros - libc.src.__support.CPP.limits - libc.src.__support.CPP.type_traits - libc.src.__support.common -) - -add_header_library( - wcs_to_integer - HDRS - wcs_to_integer.h - DEPENDS .wctype_utils - .str_to_num_result libc.hdr.errno_macros libc.src.__support.CPP.limits libc.src.__support.CPP.type_traits diff --git a/libc/src/__support/str_to_integer.h b/libc/src/__support/str_to_integer.h index d332c92..ba3f49f 100644 --- a/libc/src/__support/str_to_integer.h +++ b/libc/src/__support/str_to_integer.h @@ -25,36 +25,63 @@ #include "src/__support/macros/config.h" #include "src/__support/str_to_num_result.h" #include "src/__support/uint128.h" +#include "src/__support/wctype_utils.h" namespace LIBC_NAMESPACE_DECL { namespace internal { // Returns the idx to the first character in src that is not a whitespace -// character (as determined by isspace()) +// character (as determined by isspace() / iswspace()) +template <typename CharType> LIBC_INLINE size_t -first_non_whitespace(const char *__restrict src, +first_non_whitespace(const CharType *__restrict src, size_t src_len = cpp::numeric_limits<size_t>::max()) { size_t src_cur = 0; - while (src_cur < src_len && internal::isspace(src[src_cur])) { + while (src_cur < src_len) { + if constexpr (cpp::is_same_v<CharType, char>) { + if (!internal::isspace(src[src_cur])) + break; + } else { + if (!internal::iswspace(src[src_cur])) + break; + } ++src_cur; } return src_cur; } +// Returns +1, -1, or 0 if 'src' starts with (respectively) +// plus sign, minus sign, or neither. +template <typename CharType> +LIBC_INLINE static int get_sign(const CharType *__restrict src) { + if constexpr (cpp::is_same_v<CharType, char>) { + return (src[0] == '+') ? 1 : (src[0] == '-' ? -1 : 0); + } else { + return (src[0] == L'+') ? 1 : (src[0] == L'-' ? -1 : 0); + } +} + // checks if the next 3 characters of the string pointer are the start of a // hexadecimal number. Does not advance the string pointer. -LIBC_INLINE bool -is_hex_start(const char *__restrict src, - size_t src_len = cpp::numeric_limits<size_t>::max()) { +template <typename CharType> +LIBC_INLINE static bool is_hex_start(const CharType *__restrict src, + size_t src_len) { if (src_len < 3) return false; - return *src == '0' && tolower(*(src + 1)) == 'x' && isalnum(*(src + 2)) && - b36_char_to_int(*(src + 2)) < 16; + if constexpr (cpp::is_same_v<CharType, char>) { + return src[0] == '0' && tolower(src[1]) == 'x' && isalnum(src[2]) && + b36_char_to_int(src[2]) < 16; + } else { + return src[0] == L'0' && towlower(src[1]) == L'x' && iswalnum(src[2]) && + b36_wchar_to_int(src[2]) < 16; + } } // Takes the address of the string pointer and parses the base from the start of // it. -LIBC_INLINE int infer_base(const char *__restrict src, size_t src_len) { +template <typename CharType> +LIBC_INLINE static int infer_base(const CharType *__restrict src, + size_t src_len) { // A hexadecimal number is defined as "the prefix 0x or 0X followed by a // sequence of the decimal digits and the letters a (or A) through f (or F) // with values 10 through 15 respectively." (C standard 6.4.4.1) @@ -63,8 +90,15 @@ LIBC_INLINE int infer_base(const char *__restrict src, size_t src_len) { // An octal number is defined as "the prefix 0 optionally followed by a // sequence of the digits 0 through 7 only" (C standard 6.4.4.1) and so any // number that starts with 0, including just 0, is an octal number. - if (src_len > 0 && src[0] == '0') - return 8; + if (src_len > 0) { + if constexpr (cpp::is_same_v<CharType, char>) { + if (src[0] == '0') + return 8; + } else { + if (src[0] == L'0') + return 8; + } + } // A decimal number is defined as beginning "with a nonzero digit and // consist[ing] of a sequence of decimal digits." (C standard 6.4.4.1) return 10; @@ -77,32 +111,27 @@ LIBC_INLINE int infer_base(const char *__restrict src, size_t src_len) { // ----------------------------------------------------------------------------- // Takes a pointer to a string and the base to convert to. This function is used // as the backend for all of the string to int functions. -template <class T> +template <typename T, typename CharType> LIBC_INLINE StrToNumResult<T> -strtointeger(const char *__restrict src, int base, +strtointeger(const CharType *__restrict src, int base, const size_t src_len = cpp::numeric_limits<size_t>::max()) { using ResultType = make_integral_or_big_int_unsigned_t<T>; - ResultType result = 0; - - bool is_number = false; - size_t src_cur = 0; - int error_val = 0; - if (src_len == 0) return {0, 0, 0}; if (base < 0 || base == 1 || base > 36) return {0, 0, EINVAL}; - src_cur = first_non_whitespace(src, src_len); - - char result_sign = '+'; - if (src[src_cur] == '+' || src[src_cur] == '-') { - result_sign = src[src_cur]; - ++src_cur; + size_t src_cur = first_non_whitespace(src, src_len); + if (src_cur == src_len) { + return {0, 0, 0}; } + int sign = get_sign(src + src_cur); + bool is_positive = (sign >= 0); + src_cur += (sign != 0); + if (base == 0) base = infer_base(src + src_cur, src_len - src_cur); @@ -110,8 +139,6 @@ strtointeger(const char *__restrict src, int base, src_cur = src_cur + 2; constexpr bool IS_UNSIGNED = cpp::is_unsigned_v<T>; - const bool is_positive = (result_sign == '+'); - ResultType constexpr NEGATIVE_MAX = !IS_UNSIGNED ? static_cast<ResultType>(cpp::numeric_limits<T>::max()) + 1 : cpp::numeric_limits<T>::max(); @@ -120,8 +147,21 @@ strtointeger(const char *__restrict src, int base, ResultType const abs_max_div_by_base = abs_max / static_cast<ResultType>(base); - while (src_cur < src_len && isalnum(src[src_cur])) { - int cur_digit = b36_char_to_int(src[src_cur]); + bool is_number = false; + int error_val = 0; + ResultType result = 0; + while (src_cur < src_len) { + int cur_digit; + if constexpr (cpp::is_same_v<CharType, char>) { + if (!isalnum(src[src_cur])) + break; + cur_digit = b36_char_to_int(src[src_cur]); + } else { + if (!iswalnum(src[src_cur])) + break; + cur_digit = b36_wchar_to_int(src[src_cur]); + } + if (cur_digit >= base) break; diff --git a/libc/src/__support/wcs_to_integer.h b/libc/src/__support/wcs_to_integer.h deleted file mode 100644 index 4254bd8..0000000 --- a/libc/src/__support/wcs_to_integer.h +++ /dev/null @@ -1,155 +0,0 @@ -//===-- Widechar string to integer conversion utils -------------*- C++ -*-===// -// -// 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_SRC___SUPPORT_WCS_TO_INTEGER_H -#define LLVM_LIBC_SRC___SUPPORT_WCS_TO_INTEGER_H - -#include "hdr/errno_macros.h" // For ERANGE -#include "src/__support/CPP/limits.h" -#include "src/__support/CPP/type_traits.h" -#include "src/__support/CPP/type_traits/make_unsigned.h" -#include "src/__support/big_int.h" -#include "src/__support/common.h" -#include "src/__support/macros/config.h" -#include "src/__support/str_to_num_result.h" -#include "src/__support/uint128.h" -#include "src/__support/wctype_utils.h" - -namespace LIBC_NAMESPACE_DECL { -namespace internal { - -// Returns the idx of the first character in src that is not a whitespace -// character (as determined by iswspace()) -LIBC_INLINE size_t -first_non_whitespace(const wchar_t *__restrict src, - size_t src_len = cpp::numeric_limits<size_t>::max()) { - size_t src_cur = 0; - while (src_cur < src_len && internal::iswspace(src[src_cur])) { - ++src_cur; - } - return src_cur; -} - -// checks if the next 3 characters of the string pointer are the start of a -// hexadecimal number. Does not advance the string pointer. -LIBC_INLINE bool -is_hex_start(const wchar_t *__restrict src, - size_t src_len = cpp::numeric_limits<size_t>::max()) { - if (src_len < 3) - return false; - return *src == L'0' && towlower(*(src + 1)) == L'x' && iswalnum(*(src + 2)) && - b36_wchar_to_int(*(src + 2)) < 16; -} - -// Takes the address of the string pointer and parses the base from the start of -// it. -LIBC_INLINE int infer_base(const wchar_t *__restrict src, size_t src_len) { - // A hexadecimal number is defined as "the prefix 0x or 0X followed by a - // sequence of the decimal digits and the letters a (or A) through f (or F) - // with values 10 through 15 respectively." (C standard 6.4.4.1) - if (is_hex_start(src, src_len)) - return 16; - // An octal number is defined as "the prefix 0 optionally followed by a - // sequence of the digits 0 through 7 only" (C standard 6.4.4.1) and so any - // number that starts with 0, including just 0, is an octal number. - if (src_len > 0 && src[0] == L'0') - return 8; - // A decimal number is defined as beginning "with a nonzero digit and - // consist[ing] of a sequence of decimal digits." (C standard 6.4.4.1) - return 10; -} - -template <class T> -LIBC_INLINE StrToNumResult<T> -wcstointeger(const wchar_t *__restrict src, int base, - const size_t src_len = cpp::numeric_limits<size_t>::max()) { - using ResultType = make_integral_or_big_int_unsigned_t<T>; - - ResultType result = 0; - - bool is_number = false; - size_t src_cur = 0; - int error_val = 0; - - if (src_len == 0) - return {0, 0, 0}; - - if (base < 0 || base == 1 || base > 36) - return {0, 0, EINVAL}; - - src_cur = first_non_whitespace(src, src_len); - - wchar_t result_sign = L'+'; - if (src[src_cur] == L'+' || src[src_cur] == L'-') { - result_sign = src[src_cur]; - ++src_cur; - } - - if (base == 0) - base = infer_base(src + src_cur, src_len - src_cur); - - if (base == 16 && is_hex_start(src + src_cur, src_len - src_cur)) - src_cur = src_cur + 2; - - constexpr bool IS_UNSIGNED = cpp::is_unsigned_v<T>; - const bool is_positive = (result_sign == L'+'); - - ResultType constexpr NEGATIVE_MAX = - !IS_UNSIGNED ? static_cast<ResultType>(cpp::numeric_limits<T>::max()) + 1 - : cpp::numeric_limits<T>::max(); - ResultType const abs_max = - (is_positive ? cpp::numeric_limits<T>::max() : NEGATIVE_MAX); - ResultType const abs_max_div_by_base = - abs_max / static_cast<ResultType>(base); - - while (src_cur < src_len && iswalnum(src[src_cur])) { - int cur_digit = b36_wchar_to_int(src[src_cur]); - if (cur_digit >= base) - break; - - is_number = true; - ++src_cur; - - // If the number has already hit the maximum value for the current type then - // the result cannot change, but we still need to advance src to the end of - // the number. - if (result == abs_max) { - error_val = ERANGE; - continue; - } - - if (result > abs_max_div_by_base) { - result = abs_max; - error_val = ERANGE; - } else { - result = result * static_cast<ResultType>(base); - } - if (result > abs_max - static_cast<ResultType>(cur_digit)) { - result = abs_max; - error_val = ERANGE; - } else { - result = result + static_cast<ResultType>(cur_digit); - } - } - - ptrdiff_t str_len = is_number ? static_cast<ptrdiff_t>(src_cur) : 0; - - if (error_val == ERANGE) { - if (is_positive || IS_UNSIGNED) - return {cpp::numeric_limits<T>::max(), str_len, error_val}; - else // T is signed and there is a negative overflow - return {cpp::numeric_limits<T>::min(), str_len, error_val}; - } - - return {static_cast<T>(is_positive ? result : -result), str_len, error_val}; -} - -} // namespace internal -} // namespace LIBC_NAMESPACE_DECL - -#endif // LLVM_LIBC_SRC___SUPPORT_WCS_TO_INTEGER_H diff --git a/libc/src/fenv/CMakeLists.txt b/libc/src/fenv/CMakeLists.txt index c5431b1..f368845 100644 --- a/libc/src/fenv/CMakeLists.txt +++ b/libc/src/fenv/CMakeLists.txt @@ -6,8 +6,6 @@ add_entrypoint_object( fegetround.h DEPENDS libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -18,8 +16,6 @@ add_entrypoint_object( fesetround.h DEPENDS libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -30,8 +26,6 @@ add_entrypoint_object( feclearexcept.h DEPENDS libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -42,8 +36,6 @@ add_entrypoint_object( feraiseexcept.h DEPENDS libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -54,8 +46,6 @@ add_entrypoint_object( fetestexcept.h DEPENDS libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -67,8 +57,6 @@ add_entrypoint_object( DEPENDS libc.hdr.types.fexcept_t libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -80,8 +68,6 @@ add_entrypoint_object( DEPENDS libc.hdr.types.fenv_t libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -93,8 +79,6 @@ add_entrypoint_object( DEPENDS libc.hdr.types.fenv_t libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -107,8 +91,6 @@ add_entrypoint_object( libc.hdr.fenv_macros libc.hdr.types.fexcept_t libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -119,8 +101,6 @@ add_entrypoint_object( fesetexcept.h DEPENDS libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -133,8 +113,6 @@ add_entrypoint_object( libc.hdr.fenv_macros libc.hdr.types.fexcept_t libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -147,8 +125,6 @@ add_entrypoint_object( libc.hdr.fenv_macros libc.hdr.types.fenv_t libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -161,8 +137,6 @@ add_entrypoint_object( libc.hdr.fenv_macros libc.hdr.types.fenv_t libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -173,8 +147,6 @@ add_entrypoint_object( feenableexcept.h DEPENDS libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -185,8 +157,6 @@ add_entrypoint_object( fedisableexcept.h DEPENDS libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -197,6 +167,4 @@ add_entrypoint_object( fegetexcept.h DEPENDS libc.src.__support.FPUtil.fenv_impl - COMPILE_OPTIONS - -O2 ) diff --git a/libc/src/math/amdgpu/CMakeLists.txt b/libc/src/math/amdgpu/CMakeLists.txt index e2cd3b9..d05d519 100644 --- a/libc/src/math/amdgpu/CMakeLists.txt +++ b/libc/src/math/amdgpu/CMakeLists.txt @@ -4,8 +4,6 @@ add_entrypoint_object( ceil.cpp HDRS ../ceil.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -14,8 +12,6 @@ add_entrypoint_object( ceilf.cpp HDRS ../ceilf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -24,8 +20,6 @@ add_entrypoint_object( copysign.cpp HDRS ../copysign.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -34,8 +28,6 @@ add_entrypoint_object( copysignf.cpp HDRS ../copysignf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -44,8 +36,6 @@ add_entrypoint_object( fabs.cpp HDRS ../fabs.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -54,8 +44,6 @@ add_entrypoint_object( fabsf.cpp HDRS ../fabsf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -64,8 +52,6 @@ add_entrypoint_object( floor.cpp HDRS ../floor.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -74,8 +60,6 @@ add_entrypoint_object( floorf.cpp HDRS ../floorf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -84,8 +68,6 @@ add_entrypoint_object( fma.cpp HDRS ../fma.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -94,8 +76,6 @@ add_entrypoint_object( fmaf.cpp HDRS ../fmaf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -104,8 +84,6 @@ add_entrypoint_object( fmax.cpp HDRS ../fmax.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -114,8 +92,6 @@ add_entrypoint_object( fmaxf.cpp HDRS ../fmaxf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -124,8 +100,6 @@ add_entrypoint_object( fmin.cpp HDRS ../fmin.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -134,8 +108,6 @@ add_entrypoint_object( fminf.cpp HDRS ../fminf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -144,8 +116,6 @@ add_entrypoint_object( fmod.cpp HDRS ../fmod.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -154,8 +124,6 @@ add_entrypoint_object( fmodf.cpp HDRS ../fmodf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -164,8 +132,6 @@ add_entrypoint_object( nearbyint.cpp HDRS ../nearbyint.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -174,8 +140,6 @@ add_entrypoint_object( nearbyintf.cpp HDRS ../nearbyintf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -184,8 +148,6 @@ add_entrypoint_object( remainder.cpp HDRS ../remainder.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -194,8 +156,6 @@ add_entrypoint_object( remainderf.cpp HDRS ../remainderf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -204,8 +164,6 @@ add_entrypoint_object( rint.cpp HDRS ../rint.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -214,8 +172,6 @@ add_entrypoint_object( rintf.cpp HDRS ../rintf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -224,8 +180,6 @@ add_entrypoint_object( round.cpp HDRS ../round.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -234,8 +188,6 @@ add_entrypoint_object( sqrt.cpp HDRS ../sqrt.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -244,8 +196,6 @@ add_entrypoint_object( sqrtf.cpp HDRS ../sqrtf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -254,8 +204,6 @@ add_entrypoint_object( trunc.cpp HDRS ../trunc.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -264,8 +212,6 @@ add_entrypoint_object( truncf.cpp HDRS ../truncf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -274,8 +220,6 @@ add_entrypoint_object( frexp.cpp HDRS ../frexp.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -284,8 +228,6 @@ add_entrypoint_object( frexpf.cpp HDRS ../frexpf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -294,8 +236,6 @@ add_entrypoint_object( scalbn.cpp HDRS ../scalbn.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -304,8 +244,6 @@ add_entrypoint_object( scalbnf.cpp HDRS ../scalbnf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -314,8 +252,6 @@ add_entrypoint_object( ldexp.cpp HDRS ../ldexp.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -324,8 +260,6 @@ add_entrypoint_object( ldexpf.cpp HDRS ../ldexpf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -336,7 +270,6 @@ add_entrypoint_object( ../tgamma.h COMPILE_OPTIONS ${bitcode_link_flags} - -O2 ) add_entrypoint_object( @@ -347,7 +280,6 @@ add_entrypoint_object( ../tgammaf.h COMPILE_OPTIONS ${bitcode_link_flags} - -O2 ) add_entrypoint_object( @@ -358,7 +290,6 @@ add_entrypoint_object( ../lgamma.h COMPILE_OPTIONS ${bitcode_link_flags} - -O2 ) add_entrypoint_object( @@ -369,5 +300,4 @@ add_entrypoint_object( ../lgamma_r.h COMPILE_OPTIONS ${bitcode_link_flags} - -O2 ) diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index 6068c36..c048a64 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -2662,8 +2662,6 @@ add_entrypoint_object( ../fmaximum_mag.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -2674,8 +2672,6 @@ add_entrypoint_object( ../fmaximum_magf.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -2686,8 +2682,6 @@ add_entrypoint_object( ../fmaximum_magl.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -2735,8 +2729,6 @@ add_entrypoint_object( ../fmaximum_mag_num.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -2747,8 +2739,6 @@ add_entrypoint_object( ../fmaximum_mag_numf.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -2759,8 +2749,6 @@ add_entrypoint_object( ../fmaximum_mag_numl.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -2954,8 +2942,6 @@ add_entrypoint_object( ../fminimum_mag.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -2966,8 +2952,6 @@ add_entrypoint_object( ../fminimum_magf.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -2978,8 +2962,6 @@ add_entrypoint_object( ../fminimum_magl.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -3027,8 +3009,6 @@ add_entrypoint_object( ../fminimum_mag_num.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -3039,8 +3019,6 @@ add_entrypoint_object( ../fminimum_mag_numf.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -3051,8 +3029,6 @@ add_entrypoint_object( ../fminimum_mag_numl.h DEPENDS libc.src.__support.FPUtil.basic_operations - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -4306,7 +4282,7 @@ add_entrypoint_object( libc.hdr.errno_macros libc.hdr.fenv_macros libc.src.__support.FPUtil.except_value_utils - libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization @@ -4546,8 +4522,6 @@ add_entrypoint_object( atan.cpp HDRS ../atan.h - COMPILE_OPTIONS - -O3 DEPENDS libc.src.__support.math.atan ) diff --git a/libc/src/math/nvptx/CMakeLists.txt b/libc/src/math/nvptx/CMakeLists.txt index fcb2870..e27c316 100644 --- a/libc/src/math/nvptx/CMakeLists.txt +++ b/libc/src/math/nvptx/CMakeLists.txt @@ -4,8 +4,6 @@ add_entrypoint_object( ceil.cpp HDRS ../ceil.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -14,8 +12,6 @@ add_entrypoint_object( ceilf.cpp HDRS ../ceilf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -24,8 +20,6 @@ add_entrypoint_object( copysign.cpp HDRS ../copysign.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -34,8 +28,6 @@ add_entrypoint_object( copysignf.cpp HDRS ../copysignf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -44,8 +36,6 @@ add_entrypoint_object( fabs.cpp HDRS ../fabs.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -54,8 +44,6 @@ add_entrypoint_object( fabsf.cpp HDRS ../fabsf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -64,8 +52,6 @@ add_entrypoint_object( floor.cpp HDRS ../floor.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -74,8 +60,6 @@ add_entrypoint_object( floorf.cpp HDRS ../floorf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -84,8 +68,6 @@ add_entrypoint_object( fma.cpp HDRS ../fma.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -94,8 +76,6 @@ add_entrypoint_object( fmaf.cpp HDRS ../fmaf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -104,8 +84,6 @@ add_entrypoint_object( fmax.cpp HDRS ../fmax.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -114,8 +92,6 @@ add_entrypoint_object( fmaxf.cpp HDRS ../fmaxf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -124,8 +100,6 @@ add_entrypoint_object( fmin.cpp HDRS ../fmin.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -134,8 +108,6 @@ add_entrypoint_object( fminf.cpp HDRS ../fminf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -144,8 +116,6 @@ add_entrypoint_object( fmod.cpp HDRS ../fmod.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -154,8 +124,6 @@ add_entrypoint_object( fmodf.cpp HDRS ../fmodf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -164,8 +132,6 @@ add_entrypoint_object( nearbyint.cpp HDRS ../nearbyint.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -174,8 +140,6 @@ add_entrypoint_object( nearbyintf.cpp HDRS ../nearbyintf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -184,8 +148,6 @@ add_entrypoint_object( remainder.cpp HDRS ../remainder.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -194,8 +156,6 @@ add_entrypoint_object( remainderf.cpp HDRS ../remainderf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -204,8 +164,6 @@ add_entrypoint_object( rint.cpp HDRS ../rint.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -214,8 +172,6 @@ add_entrypoint_object( rintf.cpp HDRS ../rintf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -224,8 +180,6 @@ add_entrypoint_object( round.cpp HDRS ../round.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -234,8 +188,6 @@ add_entrypoint_object( sqrt.cpp HDRS ../sqrt.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -244,8 +196,6 @@ add_entrypoint_object( sqrtf.cpp HDRS ../sqrtf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -254,8 +204,6 @@ add_entrypoint_object( trunc.cpp HDRS ../trunc.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -264,8 +212,6 @@ add_entrypoint_object( truncf.cpp HDRS ../truncf.h - COMPILE_OPTIONS - -O2 ) add_entrypoint_object( @@ -276,7 +222,6 @@ add_entrypoint_object( ../tgamma.h COMPILE_OPTIONS ${bitcode_link_flags} - -O2 ) add_entrypoint_object( @@ -287,7 +232,6 @@ add_entrypoint_object( ../tgammaf.h COMPILE_OPTIONS ${bitcode_link_flags} - -O2 ) add_entrypoint_object( @@ -298,7 +242,6 @@ add_entrypoint_object( ../lgamma.h COMPILE_OPTIONS ${bitcode_link_flags} - -O2 ) add_entrypoint_object( @@ -309,5 +252,4 @@ add_entrypoint_object( ../lgamma_r.h COMPILE_OPTIONS ${bitcode_link_flags} - -O2 ) diff --git a/libc/src/time/strftime.cpp b/libc/src/time/strftime.cpp index f36091b..89b7d9b 100644 --- a/libc/src/time/strftime.cpp +++ b/libc/src/time/strftime.cpp @@ -26,7 +26,7 @@ LLVM_LIBC_FUNCTION(size_t, strftime, int ret = strftime_core::strftime_main(&writer, format, timeptr); if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer. wb.buff[wb.buff_cur] = '\0'; - return (ret < 0 || static_cast<size_t>(ret) > buffsz) ? 0 : ret; + return (ret < 0 || static_cast<size_t>(ret) >= buffsz) ? 0 : ret; } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/time/strftime_l.cpp b/libc/src/time/strftime_l.cpp index 201b85d..409f868 100644 --- a/libc/src/time/strftime_l.cpp +++ b/libc/src/time/strftime_l.cpp @@ -29,7 +29,7 @@ LLVM_LIBC_FUNCTION(size_t, strftime_l, int ret = strftime_core::strftime_main(&writer, format, timeptr); if (buffsz > 0) // if the buffsz is 0 the buffer may be a null pointer. wb.buff[wb.buff_cur] = '\0'; - return (ret < 0 || static_cast<size_t>(ret) > buffsz) ? 0 : ret; + return (ret < 0 || static_cast<size_t>(ret) >= buffsz) ? 0 : ret; } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wchar/CMakeLists.txt b/libc/src/wchar/CMakeLists.txt index adde382..ba27cd7 100644 --- a/libc/src/wchar/CMakeLists.txt +++ b/libc/src/wchar/CMakeLists.txt @@ -63,7 +63,7 @@ add_entrypoint_object( wcstol.h DEPENDS libc.src.errno.errno - libc.src.__support.wcs_to_integer + libc.src.__support.str_to_integer ) add_entrypoint_object( @@ -74,7 +74,7 @@ add_entrypoint_object( wcstoll.h DEPENDS libc.src.errno.errno - libc.src.__support.wcs_to_integer + libc.src.__support.str_to_integer ) add_entrypoint_object( @@ -85,7 +85,7 @@ add_entrypoint_object( wcstoul.h DEPENDS libc.src.errno.errno - libc.src.__support.wcs_to_integer + libc.src.__support.str_to_integer ) add_entrypoint_object( @@ -96,7 +96,7 @@ add_entrypoint_object( wcstoull.h DEPENDS libc.src.errno.errno - libc.src.__support.wcs_to_integer + libc.src.__support.str_to_integer ) add_entrypoint_object( diff --git a/libc/src/wchar/wcstol.cpp b/libc/src/wchar/wcstol.cpp index a05718f..a56b5f9 100644 --- a/libc/src/wchar/wcstol.cpp +++ b/libc/src/wchar/wcstol.cpp @@ -10,14 +10,14 @@ #include "src/__support/common.h" #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" -#include "src/__support/wcs_to_integer.h" +#include "src/__support/str_to_integer.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(long, wcstol, (const wchar_t *__restrict str, wchar_t **__restrict str_end, int base)) { - auto result = internal::wcstointeger<long>(str, base); + auto result = internal::strtointeger<long>(str, base); if (result.has_error()) libc_errno = result.error; diff --git a/libc/src/wchar/wcstoll.cpp b/libc/src/wchar/wcstoll.cpp index de1299d..6229d24 100644 --- a/libc/src/wchar/wcstoll.cpp +++ b/libc/src/wchar/wcstoll.cpp @@ -10,14 +10,14 @@ #include "src/__support/common.h" #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" -#include "src/__support/wcs_to_integer.h" +#include "src/__support/str_to_integer.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(long long, wcstoll, (const wchar_t *__restrict str, wchar_t **__restrict str_end, int base)) { - auto result = internal::wcstointeger<long long>(str, base); + auto result = internal::strtointeger<long long>(str, base); if (result.has_error()) libc_errno = result.error; diff --git a/libc/src/wchar/wcstoul.cpp b/libc/src/wchar/wcstoul.cpp index 79b8c9b..c5639be 100644 --- a/libc/src/wchar/wcstoul.cpp +++ b/libc/src/wchar/wcstoul.cpp @@ -10,14 +10,14 @@ #include "src/__support/common.h" #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" -#include "src/__support/wcs_to_integer.h" +#include "src/__support/str_to_integer.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(unsigned long, wcstoul, (const wchar_t *__restrict str, wchar_t **__restrict str_end, int base)) { - auto result = internal::wcstointeger<unsigned long>(str, base); + auto result = internal::strtointeger<unsigned long>(str, base); if (result.has_error()) libc_errno = result.error; diff --git a/libc/src/wchar/wcstoull.cpp b/libc/src/wchar/wcstoull.cpp index 768e03c..2ab24e9 100644 --- a/libc/src/wchar/wcstoull.cpp +++ b/libc/src/wchar/wcstoull.cpp @@ -10,14 +10,14 @@ #include "src/__support/common.h" #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" -#include "src/__support/wcs_to_integer.h" +#include "src/__support/str_to_integer.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(unsigned long long, wcstoull, (const wchar_t *__restrict str, wchar_t **__restrict str_end, int base)) { - auto result = internal::wcstointeger<unsigned long long>(str, base); + auto result = internal::strtointeger<unsigned long long>(str, base); if (result.has_error()) libc_errno = result.error; diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt index a025141..138866b 100644 --- a/libc/test/src/__support/CMakeLists.txt +++ b/libc/test/src/__support/CMakeLists.txt @@ -151,7 +151,7 @@ add_libc_test( wcs_to_integer_test.cpp DEPENDS libc.src.__support.integer_literals - libc.src.__support.wcs_to_integer + libc.src.__support.str_to_integer ) add_libc_test( diff --git a/libc/test/src/__support/str_to_integer_test.cpp b/libc/test/src/__support/str_to_integer_test.cpp index 1ec882b..e5ac1d6 100644 --- a/libc/test/src/__support/str_to_integer_test.cpp +++ b/libc/test/src/__support/str_to_integer_test.cpp @@ -49,12 +49,14 @@ TEST(LlvmLibcStrToIntegerTest, LeadingSpaces) { EXPECT_EQ(result.parsed_len, ptrdiff_t(7)); ASSERT_EQ(result.value, 12); - result = LIBC_NAMESPACE::internal::strtointeger<int>(" 12345", 10, 5); + // Use a non-null-terminated buffer to test for possible OOB access. + char buf[5] = {' ', ' ', ' ', ' ', ' '}; + result = LIBC_NAMESPACE::internal::strtointeger<int>(buf, 10, 5); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); - result = LIBC_NAMESPACE::internal::strtointeger<int>(" 12345", 10, 0); + result = LIBC_NAMESPACE::internal::strtointeger<int>(buf, 10, 0); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); diff --git a/libc/test/src/__support/wcs_to_integer_test.cpp b/libc/test/src/__support/wcs_to_integer_test.cpp index 4554968..38af778 100644 --- a/libc/test/src/__support/wcs_to_integer_test.cpp +++ b/libc/test/src/__support/wcs_to_integer_test.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/__support/wcs_to_integer.h" +#include "src/__support/str_to_integer.h" #include <stddef.h> #include "test/UnitTest/Test.h" @@ -14,224 +14,226 @@ // This file is for testing the src_len argument and other internal interface // features. Primary testing is done through the public interface. -TEST(LlvmLibcStrToIntegerTest, SimpleLength) { - auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"12345", 10, 10); +TEST(LlvmLibcWcsToIntegerTest, SimpleLength) { + auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"12345", 10, 10); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(5)); ASSERT_EQ(result.value, 12345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"12345", 10, 2); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"12345", 10, 2); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(2)); ASSERT_EQ(result.value, 12); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"12345", 10, 0); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"12345", 10, 0); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); } -TEST(LlvmLibcStrToIntegerTest, LeadingSpaces) { +TEST(LlvmLibcWcsToIntegerTest, LeadingSpaces) { auto result = - LIBC_NAMESPACE::internal::wcstointeger<int>(L" 12345", 10, 15); + LIBC_NAMESPACE::internal::strtointeger<int>(L" 12345", 10, 15); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(10)); ASSERT_EQ(result.value, 12345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" 12345", 10, 10); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L" 12345", 10, 10); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(10)); ASSERT_EQ(result.value, 12345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" 12345", 10, 7); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L" 12345", 10, 7); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(7)); ASSERT_EQ(result.value, 12); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" 12345", 10, 5); + // Use a non-null-terminated buffer to test for possible OOB access. + wchar_t buf[5] = {L' ', L' ', L' ', L' ', L' '}; + result = LIBC_NAMESPACE::internal::strtointeger<int>(buf, 10, 5); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" 12345", 10, 0); + result = LIBC_NAMESPACE::internal::strtointeger<int>(buf, 10, 0); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); } -TEST(LlvmLibcStrToIntegerTest, LeadingSign) { - auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"+12345", 10, 10); +TEST(LlvmLibcWcsToIntegerTest, LeadingSign) { + auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"+12345", 10, 10); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(6)); ASSERT_EQ(result.value, 12345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"-12345", 10, 10); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"-12345", 10, 10); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(6)); ASSERT_EQ(result.value, -12345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"+12345", 10, 6); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"+12345", 10, 6); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(6)); ASSERT_EQ(result.value, 12345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"-12345", 10, 6); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"-12345", 10, 6); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(6)); ASSERT_EQ(result.value, -12345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"+12345", 10, 3); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"+12345", 10, 3); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(3)); ASSERT_EQ(result.value, 12); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"-12345", 10, 3); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"-12345", 10, 3); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(3)); ASSERT_EQ(result.value, -12); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"+12345", 10, 1); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"+12345", 10, 1); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"-12345", 10, 1); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"-12345", 10, 1); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"+12345", 10, 0); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"+12345", 10, 0); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"-12345", 10, 0); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"-12345", 10, 0); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); } -TEST(LlvmLibcStrToIntegerTest, Base16PrefixAutoSelect) { - auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 0, 10); +TEST(LlvmLibcWcsToIntegerTest, Base16PrefixAutoSelect) { + auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 0, 10); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(7)); ASSERT_EQ(result.value, 0x12345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 0, 7); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 0, 7); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(7)); ASSERT_EQ(result.value, 0x12345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 0, 5); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 0, 5); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(5)); ASSERT_EQ(result.value, 0x123); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 0, 2); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 0, 2); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(1)); ASSERT_EQ(result.value, 0); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 0, 0); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 0, 0); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); } -TEST(LlvmLibcStrToIntegerTest, Base16PrefixManualSelect) { - auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 16, 10); +TEST(LlvmLibcWcsToIntegerTest, Base16PrefixManualSelect) { + auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 16, 10); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(7)); ASSERT_EQ(result.value, 0x12345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 16, 7); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 16, 7); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(7)); ASSERT_EQ(result.value, 0x12345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 16, 5); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 16, 5); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(5)); ASSERT_EQ(result.value, 0x123); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 16, 2); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 16, 2); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(1)); ASSERT_EQ(result.value, 0); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"0x12345", 16, 0); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"0x12345", 16, 0); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); } -TEST(LlvmLibcStrToIntegerTest, Base8PrefixAutoSelect) { - auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 0, 10); +TEST(LlvmLibcWcsToIntegerTest, Base8PrefixAutoSelect) { + auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 0, 10); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(6)); ASSERT_EQ(result.value, 012345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 0, 6); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 0, 6); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(6)); ASSERT_EQ(result.value, 012345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 0, 4); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 0, 4); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(4)); ASSERT_EQ(result.value, 0123); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 0, 1); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 0, 1); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(1)); ASSERT_EQ(result.value, 0); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 0, 0); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 0, 0); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); } -TEST(LlvmLibcStrToIntegerTest, Base8PrefixManualSelect) { - auto result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 8, 10); +TEST(LlvmLibcWcsToIntegerTest, Base8PrefixManualSelect) { + auto result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 8, 10); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(6)); ASSERT_EQ(result.value, 012345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 8, 6); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 8, 6); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(6)); ASSERT_EQ(result.value, 012345); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 8, 4); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 8, 4); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(4)); ASSERT_EQ(result.value, 0123); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 8, 1); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 8, 1); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(1)); ASSERT_EQ(result.value, 0); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L"012345", 8, 0); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L"012345", 8, 0); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(0)); ASSERT_EQ(result.value, 0); } -TEST(LlvmLibcStrToIntegerTest, CombinedTests) { +TEST(LlvmLibcWcsToIntegerTest, CombinedTests) { auto result = - LIBC_NAMESPACE::internal::wcstointeger<int>(L" -0x123", 0, 10); + LIBC_NAMESPACE::internal::strtointeger<int>(L" -0x123", 0, 10); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(10)); ASSERT_EQ(result.value, -0x123); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" -0x123", 0, 8); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L" -0x123", 0, 8); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(8)); ASSERT_EQ(result.value, -0x1); - result = LIBC_NAMESPACE::internal::wcstointeger<int>(L" -0x123", 0, 7); + result = LIBC_NAMESPACE::internal::strtointeger<int>(L" -0x123", 0, 7); EXPECT_FALSE(result.has_error()); EXPECT_EQ(result.parsed_len, ptrdiff_t(6)); ASSERT_EQ(result.value, 0); diff --git a/libc/test/src/time/strftime_test.cpp b/libc/test/src/time/strftime_test.cpp index cac7560..52221527 100644 --- a/libc/test/src/time/strftime_test.cpp +++ b/libc/test/src/time/strftime_test.cpp @@ -2326,3 +2326,24 @@ TEST(LlvmLibcStrftimeTest, TimeFormatFullDateTime) { // size_t written = 0; // SimplePaddedNum spn; // } + +TEST(LlvmLibcStrftimeTest, BufferTooSmall) { + struct tm time; + char tiny_buffer[1]; + + time.tm_year = get_adjusted_year(2025); + time.tm_mon = 10; + time.tm_mday = 24; + + size_t written = + LIBC_NAMESPACE::strftime(tiny_buffer, sizeof(tiny_buffer), "%F", &time); + EXPECT_EQ(written, size_t{0}); + + char small_buffer[10]; + + // The string "2025-11-24" is 10 chars, + // so strftime needs 10 + 1 bytes to write the string and the null terminator. + written = + LIBC_NAMESPACE::strftime(small_buffer, sizeof(small_buffer), "%F", &time); + EXPECT_EQ(written, size_t{0}); +} diff --git a/libc/utils/hdrgen/hdrgen/enumeration.py b/libc/utils/hdrgen/hdrgen/enumeration.py index 19872082..1e0f64a 100644 --- a/libc/utils/hdrgen/hdrgen/enumeration.py +++ b/libc/utils/hdrgen/hdrgen/enumeration.py @@ -6,24 +6,14 @@ # # ==-------------------------------------------------------------------------==# -from functools import total_ordering +from hdrgen.symbol import Symbol -@total_ordering -class Enumeration: +class Enumeration(Symbol): def __init__(self, name, value): - self.name = name + super().__init__(name) self.value = value - def __eq__(self, other): - return self.name == other.name - - def __lt__(self, other): - return self.name < other.name - - def __hash__(self): - return self.name.__hash__() - def __str__(self): if self.value != None: return f"{self.name} = {self.value}" diff --git a/libc/utils/hdrgen/hdrgen/function.py b/libc/utils/hdrgen/hdrgen/function.py index f039996..4de3406 100644 --- a/libc/utils/hdrgen/hdrgen/function.py +++ b/libc/utils/hdrgen/hdrgen/function.py @@ -7,7 +7,7 @@ # ==-------------------------------------------------------------------------==# import re -from functools import total_ordering +from hdrgen.symbol import Symbol from hdrgen.type import Type @@ -37,14 +37,13 @@ KEYWORDS = [ NONIDENTIFIER = re.compile("[^a-zA-Z0-9_]+") -@total_ordering -class Function: +class Function(Symbol): def __init__( self, return_type, name, arguments, standards, guard=None, attributes=[] ): + super().__init__(name) assert return_type self.return_type = return_type - self.name = name self.arguments = [ arg if isinstance(arg, str) else arg["type"] for arg in arguments ] @@ -53,15 +52,6 @@ class Function: self.guard = guard self.attributes = attributes or [] - def __eq__(self, other): - return self.name == other.name - - def __lt__(self, other): - return self.name < other.name - - def __hash__(self): - return self.name.__hash__() - def signature_types(self): def collapse(type_string): assert type_string diff --git a/libc/utils/hdrgen/hdrgen/header.py b/libc/utils/hdrgen/hdrgen/header.py index 715d4b7..f592327 100644 --- a/libc/utils/hdrgen/hdrgen/header.py +++ b/libc/utils/hdrgen/hdrgen/header.py @@ -35,6 +35,13 @@ NONIDENTIFIER = re.compile("[^a-zA-Z0-9_]+") COMMON_HEADER = PurePosixPath("__llvm-libc-common.h") +# These "attributes" are known macros defined in COMMON_HEADER. +# Others are found in "llvm-libc-macros/{name}.h". +COMMON_ATTRIBUTES = { + "_Noreturn", + "_Returns_twice", +} + # All the canonical identifiers are in lowercase for easy maintenance. # This maps them to the pretty descriptions to generate in header comments. LIBRARY_DESCRIPTIONS = { @@ -50,9 +57,7 @@ LIBRARY_DESCRIPTIONS = { HEADER_TEMPLATE = """\ //===-- {library} header <{header}> --===// // -// 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 +{license_lines} // //===---------------------------------------------------------------------===// @@ -64,6 +69,12 @@ HEADER_TEMPLATE = """\ #endif // {guard} """ +LLVM_LICENSE_TEXT = [ + "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", +] + class HeaderFile: def __init__(self, name): @@ -74,8 +85,10 @@ class HeaderFile: self.enumerations = [] self.objects = [] self.functions = [] + self.extra_standards = {} self.standards = [] self.merge_yaml_files = [] + self.license_text = [] def add_macro(self, macro): self.macros.append(macro) @@ -98,6 +111,11 @@ class HeaderFile: self.enumerations = sorted(set(self.enumerations) | set(other.enumerations)) self.objects = sorted(set(self.objects) | set(other.objects)) self.functions = sorted(set(self.functions) | set(other.functions)) + self.extra_standards |= other.extra_standards + if self.license_text: + assert not other.license_text, "only one `license_text` allowed" + else: + self.license_text = other.license_text def all_types(self): return reduce( @@ -106,6 +124,13 @@ class HeaderFile: set(self.types), ) + def all_attributes(self): + return reduce( + lambda a, b: a | b, + [set(f.attributes) for f in self.functions], + set(), + ) + def all_standards(self): # FIXME: Only functions have the "standard" field, but all the entity # types should have one too. @@ -114,16 +139,24 @@ class HeaderFile: ) def includes(self): - return { - PurePosixPath("llvm-libc-macros") / macro.header - for macro in self.macros - if macro.header is not None - } | { - COMPILER_HEADER_TYPES.get( - typ.type_name, PurePosixPath("llvm-libc-types") / f"{typ.type_name}.h" - ) - for typ in self.all_types() - } + return ( + { + PurePosixPath("llvm-libc-macros") / macro.header + for macro in self.macros + if macro.header is not None + } + | { + COMPILER_HEADER_TYPES.get( + typ.name, + PurePosixPath("llvm-libc-types") / f"{typ.name}.h", + ) + for typ in self.all_types() + } + | { + PurePosixPath("llvm-libc-macros") / f"{attr}.h" + for attr in self.all_attributes() - COMMON_ATTRIBUTES + } + ) def header_guard(self): return "_LLVM_LIBC_" + "_".join( @@ -131,24 +164,29 @@ class HeaderFile: ) def library_description(self): + descriptions = LIBRARY_DESCRIPTIONS | self.extra_standards # If the header itself is in standard C, just call it that. if "stdc" in self.standards: - return LIBRARY_DESCRIPTIONS["stdc"] + return descriptions["stdc"] # If the header itself is in POSIX, just call it that. if "posix" in self.standards: - return LIBRARY_DESCRIPTIONS["posix"] + return descriptions["posix"] # Otherwise, consider the standards for each symbol as well. standards = self.all_standards() # Otherwise, it's described by all those that apply, but ignoring # "stdc" and "posix" since this is not a "stdc" or "posix" header. return " / ".join( sorted( - LIBRARY_DESCRIPTIONS[standard] + descriptions[standard] for standard in standards if standard not in {"stdc", "posix"} ) ) + def license_lines(self): + lines = self.license_text or LLVM_LICENSE_TEXT + return "\n".join([f"// {line}" for line in lines]) + def template(self, dir, files_read): if self.template_file is not None: # There's a custom template file, so just read it in and record @@ -162,6 +200,7 @@ class HeaderFile: library=self.library_description(), header=self.name, guard=self.header_guard(), + license_lines=self.license_lines(), ) def public_api(self): @@ -188,7 +227,7 @@ class HeaderFile: ) ] - for macro in self.macros: + for macro in sorted(self.macros): # When there is nothing to define, the Macro object converts to str # as an empty string. Don't emit a blank line for those cases. if str(macro): @@ -203,7 +242,12 @@ class HeaderFile: content.append("\n__BEGIN_C_DECLS\n") current_guard = None - for function in self.functions: + last_name = None + for function in sorted(self.functions): + # If the last function's name was the same after underscores, + # elide the blank line between the declarations. + if last_name == function.name_without_underscores(): + content.pop() if function.guard == None and current_guard == None: content.append(str(function) + " __NOEXCEPT;") content.append("") @@ -225,6 +269,7 @@ class HeaderFile: content.append(f"#ifdef {current_guard}") content.append(str(function) + " __NOEXCEPT;") content.append("") + last_name = function.name_without_underscores() if current_guard != None: content.pop() content.append(f"#endif // {current_guard}") diff --git a/libc/utils/hdrgen/hdrgen/macro.py b/libc/utils/hdrgen/hdrgen/macro.py index e42e828..4664d9f 100644 --- a/libc/utils/hdrgen/hdrgen/macro.py +++ b/libc/utils/hdrgen/hdrgen/macro.py @@ -6,25 +6,15 @@ # # ==-------------------------------------------------------------------------==# -from functools import total_ordering +from hdrgen.symbol import Symbol -@total_ordering -class Macro: +class Macro(Symbol): def __init__(self, name, value=None, header=None): - self.name = name + super().__init__(name) self.value = value self.header = header - def __eq__(self, other): - return self.name == other.name - - def __lt__(self, other): - return self.name < other.name - - def __hash__(self): - return self.name.__hash__() - def __str__(self): if self.header != None: return "" diff --git a/libc/utils/hdrgen/hdrgen/main.py b/libc/utils/hdrgen/hdrgen/main.py index 25df41e..c12e89e 100755 --- a/libc/utils/hdrgen/hdrgen/main.py +++ b/libc/utils/hdrgen/hdrgen/main.py @@ -105,6 +105,7 @@ def main(): return 2 header.merge(merge_from_header) + assert header.name, f"`header: name.h` line is required in {yaml_file}" return header if args.json: diff --git a/libc/utils/hdrgen/hdrgen/object.py b/libc/utils/hdrgen/hdrgen/object.py index a311c37..a2ab496b 100644 --- a/libc/utils/hdrgen/hdrgen/object.py +++ b/libc/utils/hdrgen/hdrgen/object.py @@ -6,23 +6,13 @@ # # ==-------------------------------------------------------------------------==# -from functools import total_ordering +from hdrgen.symbol import Symbol -@total_ordering -class Object: +class Object(Symbol): def __init__(self, name, type): - self.name = name + super().__init__(name) self.type = type - def __eq__(self, other): - return self.name == other.name - - def __lt__(self, other): - return self.name < other.name - - def __hash__(self): - return self.name.__hash__() - def __str__(self): return f"extern {self.type} {self.name};" diff --git a/libc/utils/hdrgen/hdrgen/symbol.py b/libc/utils/hdrgen/hdrgen/symbol.py new file mode 100644 index 0000000..28e9def --- /dev/null +++ b/libc/utils/hdrgen/hdrgen/symbol.py @@ -0,0 +1,41 @@ +# ====-- Symbol class for libc function headers----------------*- python -*--==# +# +# 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 +# +# ==-------------------------------------------------------------------------==# + +from functools import total_ordering + + +@total_ordering +class Symbol: + """ + Symbol is the common superclass for each kind of entity named by an + identifier. It provides the name field, and defines sort ordering, + hashing, and equality based only on the name. The sorting is pretty + presentation order for identifiers, which is to say it first sorts + lexically but ignores leading underscores and secondarily sorts with the + fewest underscores first. + """ + + def __init__(self, name): + assert name + self.name = name + + def __eq__(self, other): + return self.name == other.name + + def __hash__(self): + return self.name.__hash__() + + def name_without_underscores(self): + return self.name.lstrip("_") + + def name_sort_key(self): + ident = self.name_without_underscores() + return ident, len(self.name) - len(ident) + + def __lt__(self, other): + return self.name_sort_key() < other.name_sort_key() diff --git a/libc/utils/hdrgen/hdrgen/type.py b/libc/utils/hdrgen/hdrgen/type.py index 0c0af85..20c1881 100644 --- a/libc/utils/hdrgen/hdrgen/type.py +++ b/libc/utils/hdrgen/hdrgen/type.py @@ -6,20 +6,10 @@ # # ==-------------------------------------------------------------------------==# -from functools import total_ordering +from hdrgen.symbol import Symbol -@total_ordering -class Type: - def __init__(self, type_name): - assert type_name - self.type_name = type_name - - def __eq__(self, other): - return self.type_name == other.type_name - - def __lt__(self, other): - return self.type_name < other.type_name - - def __hash__(self): - return self.type_name.__hash__() +class Type(Symbol): + # A type so far carries no specific information beyond its name. + def __init__(self, name): + super().__init__(name) diff --git a/libc/utils/hdrgen/hdrgen/yaml_to_classes.py b/libc/utils/hdrgen/hdrgen/yaml_to_classes.py index ebe7781d..9eddbe6 100644 --- a/libc/utils/hdrgen/hdrgen/yaml_to_classes.py +++ b/libc/utils/hdrgen/hdrgen/yaml_to_classes.py @@ -37,6 +37,8 @@ def yaml_to_classes(yaml_data, header_class, entry_points=None): header = header_class(header_name) header.template_file = yaml_data.get("header_template") header.standards = yaml_data.get("standards", []) + header.extra_standards = yaml_data.get("extra_standards", {}) + header.license_text = yaml_data.get("license_text", []) header.merge_yaml_files = yaml_data.get("merge_yaml_files", []) for macro_data in yaml_data.get("macros", []): diff --git a/libc/utils/hdrgen/tests/expected_output/custom.h b/libc/utils/hdrgen/tests/expected_output/custom.h new file mode 100644 index 0000000..5f9ed23 --- /dev/null +++ b/libc/utils/hdrgen/tests/expected_output/custom.h @@ -0,0 +1,21 @@ +//===-- Wile E. Coyote header <custom.h> --===// +// +// Caveat emptor. +// I never studied law. +// +//===---------------------------------------------------------------------===// + +#ifndef _LLVM_LIBC_CUSTOM_H +#define _LLVM_LIBC_CUSTOM_H + +#include "__llvm-libc-common.h" +#include "llvm-libc-types/meep.h" +#include "llvm-libc-types/road.h" + +__BEGIN_C_DECLS + +road runner(meep, meep) __NOEXCEPT; + +__END_C_DECLS + +#endif // _LLVM_LIBC_CUSTOM_H diff --git a/libc/utils/hdrgen/tests/expected_output/sorting.h b/libc/utils/hdrgen/tests/expected_output/sorting.h new file mode 100644 index 0000000..a091a42 --- /dev/null +++ b/libc/utils/hdrgen/tests/expected_output/sorting.h @@ -0,0 +1,24 @@ +//===-- Standard C header <sorting.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_SORTING_H +#define _LLVM_LIBC_SORTING_H + +#include "__llvm-libc-common.h" + +__BEGIN_C_DECLS + +void func_with_aliases(int) __NOEXCEPT; +void _func_with_aliases(int) __NOEXCEPT; +void __func_with_aliases(int) __NOEXCEPT; + +void gunk(const char *) __NOEXCEPT; + +__END_C_DECLS + +#endif // _LLVM_LIBC_SORTING_H diff --git a/libc/utils/hdrgen/tests/expected_output/test_header.h b/libc/utils/hdrgen/tests/expected_output/test_header.h index 748c098..49112a3 100644 --- a/libc/utils/hdrgen/tests/expected_output/test_header.h +++ b/libc/utils/hdrgen/tests/expected_output/test_header.h @@ -12,6 +12,7 @@ #include "__llvm-libc-common.h" #include "llvm-libc-macros/float16-macros.h" +#include "llvm-libc-macros/CONST_FUNC_A.h" #include "llvm-libc-macros/test_more-macros.h" #include "llvm-libc-macros/test_small-macros.h" #include "llvm-libc-types/float128.h" diff --git a/libc/utils/hdrgen/tests/expected_output/test_small.json b/libc/utils/hdrgen/tests/expected_output/test_small.json index 9cc73d0..8502df2 100644 --- a/libc/utils/hdrgen/tests/expected_output/test_small.json +++ b/libc/utils/hdrgen/tests/expected_output/test_small.json @@ -4,6 +4,7 @@ "standards": [], "includes": [ "__llvm-libc-common.h", + "llvm-libc-macros/CONST_FUNC_A.h", "llvm-libc-macros/test_more-macros.h", "llvm-libc-macros/test_small-macros.h", "llvm-libc-types/float128.h", diff --git a/libc/utils/hdrgen/tests/input/custom-common.yaml b/libc/utils/hdrgen/tests/input/custom-common.yaml new file mode 100644 index 0000000..909a3ba --- /dev/null +++ b/libc/utils/hdrgen/tests/input/custom-common.yaml @@ -0,0 +1,6 @@ +license_text: + - Caveat emptor. + - I never studied law. + +extra_standards: + acme: Wile E. Coyote diff --git a/libc/utils/hdrgen/tests/input/custom.yaml b/libc/utils/hdrgen/tests/input/custom.yaml new file mode 100644 index 0000000..7d3ff8e --- /dev/null +++ b/libc/utils/hdrgen/tests/input/custom.yaml @@ -0,0 +1,13 @@ +merge_yaml_files: + - custom-common.yaml + +header: custom.h +standards: + - acme + +functions: + - name: runner + return_type: road + arguments: + - type: meep + - type: meep diff --git a/libc/utils/hdrgen/tests/input/sorting.yaml b/libc/utils/hdrgen/tests/input/sorting.yaml new file mode 100644 index 0000000..3c26cde --- /dev/null +++ b/libc/utils/hdrgen/tests/input/sorting.yaml @@ -0,0 +1,20 @@ +header: sorting.h +standards: + - stdc +functions: + - name: gunk + return_type: void + arguments: + - type: const char * + - name: _func_with_aliases + return_type: void + arguments: + - type: int + - name: func_with_aliases + return_type: void + arguments: + - type: int + - name: __func_with_aliases + return_type: void + arguments: + - type: int diff --git a/libc/utils/hdrgen/tests/test_integration.py b/libc/utils/hdrgen/tests/test_integration.py index bf393d2..b975d8f 100644 --- a/libc/utils/hdrgen/tests/test_integration.py +++ b/libc/utils/hdrgen/tests/test_integration.py @@ -59,6 +59,13 @@ class TestHeaderGenIntegration(unittest.TestCase): self.run_script(yaml_file, output_file) self.compare_files(output_file, expected_output_file) + def test_custom_license_and_standards(self): + yaml_file = self.source_dir / "input" / "custom.yaml" + expected_output_file = self.source_dir / "expected_output" / "custom.h" + output_file = self.output_dir / "custom.h" + self.run_script(yaml_file, output_file) + self.compare_files(output_file, expected_output_file) + def test_generate_json(self): yaml_file = self.source_dir / "input/test_small.yaml" expected_output_file = self.source_dir / "expected_output/test_small.json" @@ -68,6 +75,13 @@ class TestHeaderGenIntegration(unittest.TestCase): self.compare_files(output_file, expected_output_file) + def test_sorting(self): + yaml_file = self.source_dir / "input" / "sorting.yaml" + expected_output_file = self.source_dir / "expected_output" / "sorting.h" + output_file = self.output_dir / "sorting.h" + self.run_script(yaml_file, output_file) + self.compare_files(output_file, expected_output_file) + def main(): parser = argparse.ArgumentParser(description="TestHeaderGenIntegration arguments") |
