aboutsummaryrefslogtreecommitdiff
path: root/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp
diff options
context:
space:
mode:
authorJan Kokemüller <jan.kokemueller@gmail.com>2024-01-22 15:05:39 +0100
committerGitHub <noreply@github.com>2024-01-22 09:05:39 -0500
commit4f4690530e8b40cdf3a17c76a352b26c2fb0446c (patch)
treec157c476049d6032b0a734ab92e73dbc6d6734e1 /libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp
parentbf7b8dae0615884816fff54cac08bc691746b1ee (diff)
downloadllvm-4f4690530e8b40cdf3a17c76a352b26c2fb0446c.zip
llvm-4f4690530e8b40cdf3a17c76a352b26c2fb0446c.tar.gz
llvm-4f4690530e8b40cdf3a17c76a352b26c2fb0446c.tar.bz2
[libc++] Ensure that std::expected has no tail padding (#69673)
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>
Diffstat (limited to 'libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp')
-rw-r--r--libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp4
1 files changed, 2 insertions, 2 deletions
diff --git a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp
index 84b57ae..ec55f63 100644
--- a/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.expected/monadic/transform_error.pass.cpp
@@ -9,8 +9,8 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// GCC has a issue for `Guaranteed copy elision for potentially-overlapping non-static data members`,
-// please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108333, but we have a workaround to
-// avoid this issue.
+// please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108333.
+// XFAIL: gcc-13
// <expected>