This was actually already implemented in the initial version of
std::expected, but this patch adds test coverage and makes it more
explicit that we intend to make these functions noexcept.
This moves the definition of a `pair` constructor for `<tuple>` to
`<__utility/pair.h>` and uses the forward declaration of `pair` in
`<tuple>` instead of including the definition.
Implement [LWG3528](https://wg21.link/LWG3528).
Based on LWG3528(https://wg21.link/LWG3528) and
http://eel.is/c++draft/description#structure.requirements-9, the
standard allows to impose requirements, we constraint
`std::make_from_tuple` to make `std::make_from_tuple` SFINAE friendly
and also avoid worse diagnostic messages. We still keep the constraints
of `std::__make_from_tuple_impl` so that `std::__make_from_tuple_impl`
will have the same advantages when used alone.
---------
Signed-off-by: yronglin <yronglin777@gmail.com>
The `parse.pass.cpp` tests doen't need to call
`test_format_context_create` to create a `basic_format_context`, so they
shouldn't include `test_format_context.h`.
The `to_address` mechanism works around the iterator debugging
mechanisms of MSVC STL. Related to
[LWG3989](https://cplusplus.github.io/LWG/issue3989).
Discovered when implementing `formatter<tuple>` in MSVC STL. With the
inclusion removed, `std/utilities/format/format.tuple/parse.pass.cpp`
when using enhanced MSVC STL (and `/utf-8` option for MSVC).
An immediate colon signifeis that the range-format-spec contains only
range-underlying-spec.
This patch allows this code to compile and run:
```c++
std::println("{::<<9?}", std::span<const char>{"Hello", sizeof "Hello"});
```
This reverts commit 7d9b5aa65b since
std/utilities/format/format.arguments/format.arg/visit.return_type.pass.cpp
is failing on Windows when building with Clang-cl.
Currently std::expected can have some padding bytes in its tail due to
[[no_unique_address]]. Those padding bytes can be used by other objects.
For example, in the current implementation:
sizeof(std::expected<std::optional<int>, bool>) ==
sizeof(std::expected<std::expected<std::optional<int>, bool>, bool>)
As a result, the data layout of an
std::expected<std::expected<std::optional<int>, bool>, bool>
can look like this:
+-- optional "has value" flag
| +--padding
/---int---\ | |
00 00 00 00 01 00 00 00
| |
| +- "outer" expected "has value" flag
|
+- expected "has value" flag
This is problematic because `emplace()`ing the "inner" expected can not
only overwrite the "inner" expected "has value" flag (issue #68552) but
also the tail padding where other objects might live.
This patch fixes the problem by ensuring that std::expected has no tail
padding, which is achieved by conditional usage of [[no_unique_address]]
based on the tail padding that this would create.
This is an ABI breaking change because the following property changes:
sizeof(std::expected<std::optional<int>, bool>) <
sizeof(std::expected<std::expected<std::optional<int>, bool>, bool>)
Before the change, this relation didn't hold. After the change, the relation
does hold, which means that the size of std::expected in these cases increases
after this patch. The data layout will change in the following cases where
tail padding can be reused by other objects:
class foo : std::expected<std::optional<int>, bool> {
bool b;
};
or using [[no_unique_address]]:
struct foo {
[[no_unique_address]] std::expected<std::optional<int>, bool> e;
bool b;
};
The vendor communication is handled in #70820.
Fixes: #70494
Co-authored-by: philnik777 <nikolasklauser@berlin.de>
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
As @cpplearner explained in microsoft/STL#4328:
> libc++'s "ascii" mode (controlled by the `_LIBCPP_HAS_NO_UNICODE`
> macro) means "every code unit outside ASCII is treated as a valid
> printable character". AFAIK we \[MSVC's STL\] don't support such a mode.
Because these files are testing a non-Standard mode, they should be
moved from `libcxx/test/std` to `libcxx/test/libcxx`.
Closes#77638, #24186
Rebased from <https://reviews.llvm.org/D156032>, see there for more
information.
Implements wording change in [CWG2137](https://wg21.link/CWG2137) in the
first commit.
This also implements an approach to [CWG2311](https://wg21.link/CWG2311)
in the second commit, because too much code that relies on `T{ T_prvalue}`
being an elision would break. Because that issue is still open and
the CWG issue doesn't provide wording to fix the issue, there may be
different behaviours on other compilers.
This was causing compilation errors when attempting to compare a
`shared_ptr<T[]>` with `nullptr`, as `get()` returns `T*` rather than `T
(*)[]`. `unique_ptr` did not have this issue, but I've added tests to
make sure.
As pointed out by @Zingam the paper was implemented in libc++ as an
extension. This patch does the bookkeeping. The inital release version
is based on historical release dates.
Completes:
- Add a conditional noexcept specification to std::apply
This patch adds a configuration of the libc++ test suite that enables
optimizations when building the tests. It also adds a new CI
configuration to exercise this on a regular basis. This is added in the
context of [1], which requires building with optimizations in order to
hit the bug.
[1]: https://github.com/llvm/llvm-project/issues/68552
Also introduce `_LIBCPP_ASSERT_PEDANTIC` for assertions violating which
results in a no-op or other benign behavior, but which may nevertheless
indicate a bug in the invoking code.
The status table incorrectly marks P0521R0 as nothing to do. This is not
correct the function should be deprecated.
During our latest monthly meeting we argreed to remove the
_LIBCPP_ENABLE_CXXyy_REMOVED_FEATURES macros, therefore the new macro is
not
added to that global list.
Implements
- P0521R0 Proposed Resolution for CA 14 (shared_ptr use_count/unique)
Implements parts of
- P0619R4 Reviewing Deprecated Facilities of C++17 for C++20
---------
Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
This patch removes assumptions that std::array's iterators are raw
pointers in the source code and in our test suite. While this is true
right now, this doesn't have to be true and ion the future we might want
to enable bounded iterators in std::array, which would require this
change.
This is a pre-requisite for landing #74482
This is the last PR that's needed (for now) to get libc++'s tests
working with MSVC's STL.
The ADDITIONAL_COMPILE_FLAGS machinery is very useful, but also very
problematic for MSVC, as it doesn't understand most of Clang's compiler
options. We've been dealing with this by simply marking anything that
uses ADDITIONAL_COMPILE_FLAGS as FAIL or SKIPPED, but that creates
significant gaps in test coverage.
Fortunately, ADDITIONAL_COMPILE_FLAGS also supports "features", which
can be slightly enhanced to send Clang-compatible and MSVC-compatible
options to the right compilers.
This patch adds the gcc-style-warnings and cl-style-warnings Lit features,
and uses that to pass the appropriate warning flags to tests. It also uses
TEST_MEOW_DIAGNOSTIC_IGNORED for a few local suppressions of MSVC
warnings.
Found while running libc++'s tests with MSVC's STL.
*
`libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/sort.heap/ranges_sort_heap.pass.cpp`
+ Fix Clang `-Wunused-variable`, because `LIBCPP_ASSERT` expands to
nothing for MSVC's STL.
+ This is the same "always void-cast" change that #73437 applied to the
neighboring `complexity.pass.cpp`. I missed that
`ranges_sort_heap.pass.cpp` was also affected because we had disabled
this test.
*
`libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/buffered_reads.pass.cpp`
*
`libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/buffered_writes.pass.cpp`
+ Fix MSVC "warning C4244: '`=`': conversion from '`__int64`' to
'`_Ty`', possible loss of data".
+ This is a valid warning, possibly the best one that MSVC found in this
entire saga. We're accumulating a `std::vector<std::streamsize>` and
storing the result in `std::streamsize total_size` but we actually have
to start with `std::streamsize{0}` or we'll truncate.
*
`libcxx/test/std/input.output/filesystems/fs.enum/enum.path.format.pass.cpp`
+ Fix Clang `-Wunused-local-typedef` because the following usage is
libc++-only.
+ I'm just expanding it at the point of use, and using the dedicated
`LIBCPP_STATIC_ASSERT` to keep the line length down.
*
`libcxx/test/std/input.output/syncstream/syncbuf/syncstream.syncbuf.assign/swap.pass.cpp`
+ Fix MSVC "warning C4242: 'argument': conversion from '`int`' to
'`const _Elem`', possible loss of data".
+ This is a valid warning (possibly the second-best) as `sputc()`
returns `int_type`. If `sputc()` returns something unexpected, we want
to know, so we should separately say `expected.push_back(CharT('B'))`.
*
`libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp`
*
`libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp`
+ Fix MSVC "warning C6001: Using uninitialized memory '`x`'."
+ [N4964](https://wg21.link/N4964) \[new.delete.single\]/12:
> *Effects:* The deallocation functions
(\[basic.stc.dynamic.deallocation\]) called by a *delete-expression*
(\[expr.delete\]) to render the value of `ptr` invalid.
+ \[basic.stc.general\]/4:
> When the end of the duration of a region of storage is reached, the
values of all pointers representing the address of any part of that
region of storage become invalid pointer values (\[basic.compound\]).
Indirection through an invalid pointer value and passing an invalid
pointer value to a deallocation function have undefined behavior. Any
other use of an invalid pointer value has implementation-defined
behavior.
+ In certain configurations, after `delete x;` MSVC will consider `x` to
be radioactive (and in other configurations, it'll physically null out
`x` as a safety measure). We can copy it into `old_x` before deletion,
which the implementation finds acceptable.
*
`libcxx/test/std/ranges/range.adaptors/range.elements/general.pass.cpp`
*
`libcxx/test/std/ranges/range.adaptors/range.elements/iterator/deref.pass.cpp`
+ Fix MSVC "warning C4242: 'initializing': conversion from '`_Ty`' to
'`_Ty`', possible loss of data".
+ This was being emitted in `pair` and `tuple`'s perfect forwarding
constructors. Passing `short{1}` allows MSVC to see that no truncation
is happening.
*
`libcxx/test/std/ranges/range.adaptors/range.elements/iterator/member_types.compile.pass.cpp`
+ Fix MSVC "warning C4242: 'initializing': conversion from '`_Ty`' to
'`_Ty2`', possible loss of data".
+ Similarly, this was being emitted in `pair`'s perfect forwarding
constructor. After passing `short{1}`, I reduced repetition by relying
on CTAD. (I can undo that cleanup if it's stylistically undesirable.)
*
`libcxx/test/std/utilities/function.objects/refwrap/refwrap.const/type_conv_ctor.pass.cpp`
+ Fix MSVC "warning C4930: '`std::reference_wrapper<int> purr(void)`':
prototyped function not called (was a variable definition intended?)".
+ There's no reason for `purr()` to be locally declared (aside from
isolating it to a narrow scope, which has minimal benefits); it can be
declared like `meow()` above. 😸
*
`libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp`
*
`libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp`
+ Fix MSVC static analysis warnings when replacing `operator new`:
```
warning C28196: The requirement that '(_Param_(1)>0)?(return!=0):(1)' is
not satisfied. (The expression does not evaluate to true.)
warning C6387: 'return' could be '0': this does not adhere to the
specification for the function 'new'.
warning C6011: Dereferencing NULL pointer 'reinterpret_cast<char
*>ptr+i'.
```
+ All we need is a null check, which appears in other `operator new`
replacements:
b85f1f9b18/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.replace.pass.cpp (L27-L28)
Found while running libc++'s tests with MSVC's STL.
*
`libcxx/test/std/algorithms/alg.modifying.operations/alg.unique/ranges_unique_copy.pass.cpp`
+ Fix MSVC "warning C4389: '`==`': signed/unsigned mismatch".
+ This was x86-specific for me. The LHS is `int` and the RHS is
`size_t`. We know the `array`'s size, so `static_cast<int>` is certainly
safe, and this matches the following `numberOfProj` comparisons.
*
`libcxx/test/std/containers/sequences/insert_range_sequence_containers.h`
+ Fix MSVC "warning C4267: 'argument': conversion from '`size_t`' to
'`const int`', possible loss of data".
+ `test_case.index` is `size_t`:
b85f1f9b18/libcxx/test/std/containers/insert_range_helpers.h (L65-L68)
+ But the container's `difference_type` is `int`:
b85f1f9b18/libcxx/test/support/test_allocator.h (L65-L76)
+ I introduced an alias `D` to make the long line more readable.
*
`libcxx/test/std/containers/unord/unord.map/eq.different_hash.pass.cpp`
*
`libcxx/test/std/containers/unord/unord.multimap/eq.different_hash.pass.cpp`
*
`libcxx/test/std/containers/unord/unord.multiset/eq.different_hash.pass.cpp`
*
`libcxx/test/std/containers/unord/unord.set/eq.different_hash.pass.cpp`
+ Fix MSVC "warning C6297: Arithmetic overflow. Results might not be an
expected value."
+ This warning is almost annoying enough to outright disable, but we use
similar `static_cast`s to deal with sign/truncation warnings elsewhere,
because there's some value in ensuring that product code is clean with
respect to these warnings. If there were many more occurrences, then
disabling the warning would be appropriate.
+ Cleanup: Change 2 inconsistently unqualified occurrences of `size_t`
to `std::size_t`.
*
`libcxx/test/std/containers/views/mdspan/layout_stride/index_operator.pass.cpp`
+ Fix MSVC "warning C4244: 'initializing': conversion from '`__int64`'
to '`size_t`', possible loss of data".
+ This was x86-specific for me. The `args` are indeed `int64_t`, and
we're storing the result in `size_t`, so we should cast.
* `libcxx/test/std/ranges/range.utility/range.utility.conv/container.h`
+ Fix MSVC "warning C4244: 'initializing': conversion from '`ptrdiff_t`'
to '`int`', possible loss of data".
+ Fix MSVC "warning C4267: 'initializing': conversion from '`size_t`' to
'`int`', possible loss of data".
+ We're initializing `int size_`, so we should explicitly cast from
pointer subtraction and `std::ranges::size`.
*
`libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_for_overwrite.pass.cpp`
*
`libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared_for_overwrite.pass.cpp`
*
`libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique_for_overwrite.default_init.pass.cpp`
+ Fix MSVC "warning C4309: 'initializing': truncation of constant
value".
+ MSVC emits this warning because `0xDE` is outside the range of `char`
(signed by default in our implementation).
* `libcxx/test/support/concat_macros.h`
+ Fix MSVC "warning C4244: 'argument': conversion from '`char16_t`' to
'`const char`', possible loss of data".
+ Fix MSVC "warning C4244: 'argument': conversion from '`unsigned int`'
to '`const char`', possible loss of data".
+ This code was very recently introduced by @mordante in #73395.
Found while running libc++'s test suite with MSVC's STL.
* In `escaped_output.unicode.pass.cpp`, replace `_LIBCPP_SHORT_WCHAR`
with `TEST_SHORT_WCHAR`.
+ This was the only test that was directly using the `_LIBCPP` macro.
`libcxx/test/support/test_macros.h` performs this mapping:
c60ac50939/libcxx/test/support/test_macros.h (L442-L444)
* In `msvc_stdlib_force_include.h`, define `TEST_SHORT_WCHAR`.
This change requires quite a number of changes in the tests; this is not
code I expect people to use in the wild. So I don't expect breakage for
users.
Implements:
- P2905R2 Runtime format strings, as a Defect Report
In preparation for running clang-format on the whole code base, we are
also removing mentions of the legacy _LIBCPP_INLINE_VISIBILITY macro in
favor of the newer _LIBCPP_HIDE_FROM_ABI.
We're still leaving the definition of _LIBCPP_INLINE_VISIBILITY to avoid
creating needless breakage in case some older patches are checked-in
with mentions of the old macro. After we branch for LLVM 18, we can do
another pass to clean up remaining uses of the macro that might have
gotten introduced by mistake (if any) and remove the macro itself at the
same time. This is just a minor convenience to smooth out the transition
as much as possible.
See
https://discourse.llvm.org/t/rfc-clang-formatting-all-of-libc-once-and-for-all
for the clang-format proposal.
Found while running libc++'s test suite with MSVC's STL, where we use
both MSVC's compiler and Clang/LLVM.
MSVC's compiler rejects the non-Standard extension of zero-length
arrays. For conformance, I'm changing these occurrences to
`std::array<int, 0>`.
Many of these files already had `#include <array>`; I'm adding it to the
rest.
I wanted to add `-Wzero-length-array` to
`libcxx/utils/libcxx/test/params.py` to prevent future occurrences, but
it complained about product code 😿 :
```
In file included from /home/runner/_work/llvm-project/llvm-project/libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long.pass.cpp:18:
In file included from /home/runner/_work/llvm-project/llvm-project/build/generic-cxx03/include/c++/v1/istream:170:
In file included from /home/runner/_work/llvm-project/llvm-project/build/generic-cxx03/include/c++/v1/ostream:172:
In file included from /home/runner/_work/llvm-project/llvm-project/build/generic-cxx03/include/c++/v1/__system_error/error_code.h:18:
In file included from /home/runner/_work/llvm-project/llvm-project/build/generic-cxx03/include/c++/v1/__system_error/error_category.h:15:
/home/runner/_work/llvm-project/llvm-project/build/generic-cxx03/include/c++/v1/string:811:25: error: zero size arrays are an extension [-Werror,-Wzero-length-array]
811 | char __padding_[sizeof(value_type) - 1];
| ^~~~~~~~~~~~~~~~~~~~~~
/home/runner/_work/llvm-project/llvm-project/build/generic-cxx03/include/c++/v1/string:817:19: note: in instantiation of member class 'std::basic_string<char>::__short' requested here
817 | static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
| ^
/home/runner/_work/llvm-project/llvm-project/build/generic-cxx03/include/c++/v1/string:2069:5: note: in instantiation of template class 'std::basic_string<char>' requested here
2069 | _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_DECLARE, char)
| ^
/home/runner/_work/llvm-project/llvm-project/build/generic-cxx03/include/c++/v1/__string/extern_template_lists.h:31:60: note: expanded from macro '_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST'
31 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
| ^
```
I pushed a tiny commit to fix unrelated comment typos, in an attempt to
clear out spurious CI failures.
This paper was voted in as a DR, so it's retroactively enabled back to
C++20; the C++ version that introduced std::format.
Implements:
- P2909R4 Fix formatting of code units as integers (Dude, where’s my
``char``?)