In a previous PR I fixed one case where subnormal long doubles would
cause an infinite loop in printf. It was an improper fix though. The
problem was that a shift on the fixed point representation would
sometimes go negative, since the effective exponent of a subnormal is
lower than the minimum allowed exponent value. This patch extends the
fixed point representation to have space for subnormals, and adds an
assert to check that lshifts are always positive. The previous fix of
sometimes shifting right instead of left caused a loss of precision
which also sometimes caused infinite loops in the %e code.
There are three flavors of WriteBuffer currently, all of which could be
passed into `printf_core::Writer` class. It's a tricky class, since it
chooses a flavor-specific logic either based on runtime dispatch (to
save code size and prevent generating three versions of the entirety of
printf_core), or based on template arguments (to avoid dealing with
function pointers in codegen for `FILL_BUFF_AND_DROP_OVERFLOW` path).
Refactor this somewhat convoluted logic to have three concrete
subclasses inheriting from the templated base class, and use static
polymorphism with `reinterpret_cast` to implement dispatching above. Now
we can actually have flavor-specific fields, constructors, and methods
(e.g. `flush_to_stream` is now a method of `FlushingBuffer`), and the
code on the user side is cleaner: the complexity of enabling/disabling
runtime-dispatch and using proper template arguments is now localized in
`writer.h`.
This code will need to be further templatized to support buffers of type
`wchar_t` to implement `swprintf()` and friends. This change would make
it (ever so slightly) easier.
This patch moves abs_timeout and monotonicity out of the linux dir into
common. Both of these functions depend on clock_gettime which is the
actual os-dependent component. As other features in `__support/threads`
may want to use these, it's better to share it in common.
[Previous commit had an incorrect default case when
FIND_FIRST_CHARACTER_WIDE_READ_IMPL was not specified in config.json.
This PR is identical to that one with one line fixed.]
As we implement more high-performance string-related functions, we have
found a need for better control over their selection than the big-hammer
LIBC_CONF_STRING_LENGTH_WIDE_READ. For example, I have a memchr
implementation coming, and unless I implement it in every variant, a
simple binary value doesn't work.
This PR makes gives finer-grained control over high-performance
functions than the generic LIBC_CONF_UNSAFE_WIDE_READ option. For any
function they like, the user can now select one of four implementations
at build time:
1. element, which reads byte-by-byte (or wchar by wchar)
2. wide, which reads by unsigned long
3. generic, which uses standard clang vector implemenations, if
available
4. arch, which uses an architecture-specific implemenation
(Reading the code carefully, you may note that a user can actually
specify any namespace they want, so we aren't technically limited to
those 4.)
We may also want to switch from command-line #defines as it is currently
done, to something more like
llvm-project/llvm/include/llvm/Config/llvm-config.h.cmake, and
complexity out of the command-line. But that's a future problem.
[This is more of a straw-proposal than a ready-for-merging PR. I got
started thinking about what this might look like, and ended up just
implementing something as a proof-of-concept. Totally open to other
methods an ideas.]
As we implement more high-performance string-related functions, we have
found a need for better control over their selection than the big-hammer
LIBC_CONF_STRING_LENGTH_WIDE_READ. For example, I have a memchr
implementation coming, and unless I implement it in every variant, a
simple binary value doesn't work.
This PR makes gives finer-grained control over high-performance
functions than the generic LIBC_CONF_UNSAFE_WIDE_READ option. For any
function they like, the user can now select one of four implementations
at build time:
1. element, which reads byte-by-byte (or wchar by wchar)
2. wide, which reads by unsigned long
3. generic, which uses standard clang vector implemenations, if
available
4. arch, which uses an architecture-specific implemenation
(Reading the code carefully, you may note that a user can actually
specify any namespace they want, so we aren't technically limited to
those 4.)
We may also want to switch from command-line #defines as it is currently
done, to something more like
llvm-project/llvm/include/llvm/Config/llvm-config.h.cmake, and
#including the resulting file, which would move quite a bit of
complexity out of the command-line. But that's a future problem.
#170525
Based on our
[RFC](https://discourse.llvm.org/t/rfc-libc-wctype-header-implementation/88941/10),
we are starting the implementation of the wctype header with C.UTF8
support. This implementation will increase the binary size by
approximately ~70KB, so this PR introduces a flag so that this is
configurable, allowing the user to choose between a simple ASCII
implementation or the full Unicode one.
clock_conversion.h implements convert_clock which shifts a timestamp
from one clock domain to another. It naturally does not depend on any OS
specific interface. Making it generic will allow common use.
Most platforms inherently have a size_t alignment of 4, but this isn't
true on every platform LLVM has some degree of backend support for.
Accordingly, it's simple enough to just set the min alignment of Block
to 4 and lose the static_assert.
They are not used anywhere except for the btowc/wctob entrypoints, so
just move the implementation there. Internal code should probably be
using a safer mbrtowc variants anyway, if applicable.
This allows us to remove the use of wint_t, which is problematic for
some uses through `libc/shared/` when a host system doesn't have
wide-character support (see PR #165884 comments). There's no such
problems with `wchar_t`, since it's a fundamental type in C++.
This patch adds support for clock_gettime for Darwin. Darwin syscall
'gettimeofday' is used to query the time from the system.
Many headers in llvm-libc-types, namely clockid_t, struct_timespec,
struct_timeval, suseconds_t, time_t_32, time_t_64, are modified to
include
header guards as Darwin has its own implementation of primitive types.
_Exit(3) is a fairly simple syscall wrapper whereas exit(3) calls
atexit-registered functions + whole lot of stuff that require support
for sync primitives.
Splitting the tests allows testing the former easily (especially for new
port projects)
---------
Signed-off-by: Shreeyash Pandey <shreeyash335@gmail.com>
Add dependency on headers with `in_addr` and `in_addr_t` type
definitions to ensure that these headers will be properly installed by
"install-libc" CMake target.
Algorithm:
```
1) atan(x) = sign(x) * atan(|x|)
2) If |x| > 1 + 1/32, atan(|x|) = pi/2 - atan(1/|x|)
3) For 1/16 < |x| < 1 + 1/32, we find k such that: | |x| - k/16 | <= 1/32.
Let y = |x| - k/16, then using the angle summation formula, we have:
atan(|x|) = atan(k/16) + atan( (|x| - k/16) / (1 + |x| * k/16) )
= atan(k/16) + atan( y / (1 + (y + k/16) * k/16 )
= atan(k/16) + atan( y / ((1 + k^2/256) + y * k/16) )
4) Let u = y / (1 + k^2/256), then we can rewritten the above as:
atan(|x|) = atan(k/16) + atan( u / (1 + u * k/16) )
~ atan(k/16) + (u - k/16 * u^2 + (k^2/256 - 1/3) * u^3 +
+ (k/16 - (k/16)^3) * u^4) + O(u^5)
```
With all the computations are done in single precision (float), the
total of approximation errors and rounding errors is bounded by 4 ULPs.
Summary:
These were originally intended to represent the functions that are
present on the GPU as to be provided by the LLVM libc implementation.
The original plan was that LLVM libc would report which functions were
supported and then the offload interface would mark those as supported.
The problem is that these wrapper headers are very difficult to make
work given the various libc extensions everyone does so they were
extremely fragile.
OpenMP already declares all functions used inside of a target region as
implicitly host / device, while these headers weren't even used for CUDA
/ HIP yet anyway. The only things we need to define right now are the
stdio FILE types. If we want to make this work for CUDA we'd need to
define these manually, but we're a ways off and that's way easier
because they do proper overloading.
Explicitly cast 0 to size_t type to match fread() return type. This
follows the pattern used elsewhere in this file, and fixes
-Wshorten-64-to-32 warnings when building the test.
This patch provides definitions for `pkey_*` functions for linux x86_64.
`pkey_alloc`, `pkey_free`, and `pkey_mprotect` are simple syscall
wrappers. `pkey_set` and `pkey_get` modify architecture-specific
registers. The logic for these live in architecture specific
directories:
* `libc/src/sys/mman/linux/x86_64/pkey_common.h` has a real
implementation
* `libc/src/sys/mman/linux/generic/pkey_common.h` contains stubs that
just return `ENOSYS`.
This patch adds the posix function `inet_addr`. Since most of the
parsing logic is delegated to `inet_aton`, I have only included some
basic smoke tests for testing purposes.
These functions should be declared in `stdlib.h`, not `wchar.h`, as
confusing as it is. Move them to the proper header file and matching
directories in src/ and test/ trees.
This was discovered while testing libc++ build against llvm-libc, which
re-declares functions like mbtowc in std-namespace in `<cstdlib>`
header, and then uses those functions in its locale implementation.
These are simply implemented as specializations of strtofloatingpoint
for double / long double and for wchar_t. The unit tests are copied from
the strtod / strtold ones.
Currently there are no 32 bit presubmit builds for libc. This PR
performs 32 bit build only (no test) to check any changes that land in
libc break 32 bit builds.
Co-authored-by: Aiden Grossman <aidengrossman@google.com>
_Exit(3) is a fairly simple syscall wrapper whereas exit(3) calls
atexit-registered functions + whole lot of stuff that require support
for sync primitives.
Splitting the tests allows testing the former easily (especially for new
port projects)
---------
Signed-off-by: Shreeyash Pandey <shreeyash335@gmail.com>
Addresses `TODO`s in file.cpp by replacing data copies via for loops
with calls to inline_memcpy.
Signed-off-by: Shreeyash Pandey <shreeyash335@gmail.com>
This change follows the pattern of
315dfe5865 by making strtofloat also
accept wchar_t* strings
(in addition to regular char*). It uses overloads from wctype_utils or
specialized functions to ensure comparison with literal characters (or
literal strings) pick char or wchar_t variants based on the argument
type.
The wcstof implementation is added, with unit test cases copied from
strtof test suite.
[libc][stdlib] Simplify getenv_test by using inline_strcmp instead of custom helper
Replace the custom `my_streq` helper function with LLVM libc's
`inline_strcmp` utility from `src/string/memory_utils/inline_strcmp.h`.
Changes:
- Remove 18-line custom `my_streq` implementation
- Use `inline_strcmp` with a simple comparator lambda for string comparisons
- Replace `my_streq(..., nullptr)` checks with direct `== nullptr` comparisons
- Maintain identical test coverage while reducing code duplication
Benefits:
- Uses existing, well-tested LLVM libc infrastructure
- Clearer test assertions with standard comparison functions
- More concise code (reduced from ~48 to ~33 lines)
- Consistent with LLVM libc coding practices
The test continues to verify:
- Empty string handling
- Invalid name handling ('=')
- Missing environment variable queries
- Correct retrieval of existing variables (FRANCE, GERMANY, PATH)
- Partial name matching behavior (FRANC vs FRANCE, FRANCE1 vs FRANCE)
When the backend for the host target isn't enabled, Clang would report
the default target as `unknown`. This currently breaks the libc CMake
build, but shouldn't in the case where we're cross-compiling since we're
given an explicit target and the default one isn't being used.
The LLVM-customized GTest has a dependency on LLVM to support
`llvm::raw_ostream` and hence has to link to LLVMSupport. The runtimes
use the LLVMSupport from the bootstrapping LLVM build. The problem is
that the boostrapping compiler and the runtimes target can diverge in
their ABI, even in the runtimes default build. For instance, Clang is
built using gcc which uses libstdc++, but the runtimes is built by Clang
which can be configured to use libcxx by default. Altough it does not
use gcc, this issue has caused
[flang-aarch64-libcxx](https://lab.llvm.org/buildbot/#/builders/89)) to
break, and is still (again?) broken.
This patch makes the runtimes' GTest independent from LLVMSupport so we
do not link any runtimes component with LLVM components.
Runtime projects that use GTest unittests:
* flang-rt
* libc
* compiler-rt: Adds `gtest-all.cpp` with
[GTEST_NO_LLVM_SUPPORT=1](f801b6f67e/compiler-rt/CMakeLists.txt (L723))
to each unittest without using `llvm_gtest`. Not touched by this PR.
* openmp: Handled by #159416. Not touched for now by this PR to avoid
conflict.
The current state of this PR tries to reuse
https://github.com/llvm/llvm-project/blob/main/third-party/unittest/CMakeLists.txt
as much as possible, altough personally I would prefer to make it use
"modern CMake" style. third-party/unittest/CMakeLists.txt will detect
whether it is used in runtimes build and adjaust accordingly. It creates
a different target for LLVM (`llvm_gtest`, NFCI) and another one for the
runtimes (`runtimes_gtest`). It is not possible to reuse `llvm_gtest`
for both since `llvm_gtest` is imported using `find_package(LLVM)` if
configured using LLVM_INSTALL_GTEST. An alias `default_gtest` is used to
select between the two. `default_gtest` could also be used for openmp
which also supports standalone and
[LLVM_ENABLE_PROJECTS](https://github.com/llvm/llvm-project/pull/152189)
build mode.
ctype_utils/wctype_utils were chaged in
120689e466 and
e7f7973899, respectively to operate on
char/wchar_t. Now we can switch to the overloaded names (e.g. have noth
`isspace(char` and `isspace(wchar_t)`) to simplify the templatized
strtointeger implementation from
315dfe5865 and make it easier to
potentially add templatized strtofloat implementation.
There is no guarantee that this environment variable is set. Eg, when
running a test outside of the build system, such as under a debugger.
And passing a nullptr to the string constructor is undefined.
Use an empty string, which seems like it is close to the original
intent.