From nobody Fri May 29 23:04:45 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gRzTB1C8fz6gFjy for ; Fri, 29 May 2026 23:04:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gRzT91CGwz3HdF for ; Fri, 29 May 2026 23:04:45 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1780095885; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=0wqIy0r4qbfZmz8nvpz/Hm4a3MYvWJZSDW4o49auajg=; b=SmopB/oQYQGBBE3nLg57CvqgddyasKsyqWbU8lTNMG9YHrg9/vdCNHqgDqn+eCIzlLHs0q xmC3VBC0YyvghoUIpViQswj++yf/Qj8+KsMrTanXJXs/vIe7y3ucin1SKx2Dfv2o4LXOJ0 AaLPX7Ojg+5ELmQKLoSRYI1NToqOJ/VaaxXd3xVCa4UUWa8yJIZE95NEn75Ku1BVcyAuKE 8lMt+DJtOqHYnoe2/S0FDgXqw/GEHixZvSoZhWf9mo+ESrk1mdKOnoT0faPIu6n53oE5Wh REKU2yGs7QA376AUqGTrcvxHqAnqnXbhuFA/jjF78DhSI0nkHEmzapQd4E099A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1780095885; a=rsa-sha256; cv=none; b=cx+crYirQmH5RlUEexVvCIJeOru7crcydK9FW/FPBo/KOG7+G8aLyZyGbjCfRQ0yBCkB0f 8KRBadqQUIYUK95E9Ujfzb8RxgmKf1pc227JHty+fPvN3t0JRM+1xhTH8yfT2pOEizVmoc eUrB0gIfRkXw1e73u5xqAk9+BU1+s86+rPHKmK6gZ9BQv4RARtyCXhdq6NDUnAalCLxqF4 ngiOncW3yYSRTKcMY3fsicGBM24WvspvctzGQfF1qDn0Hub3mlrjIu1sDn0c/c1FZOvE5Z IlAACsPhntQSykK5jk4grYhOTuGsbfOi2LxH4esCCJJqciFxPchPxgvvwAKd9A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1780095885; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=0wqIy0r4qbfZmz8nvpz/Hm4a3MYvWJZSDW4o49auajg=; b=hm8JVBb0Tt2GEm6F2+bEasdSK1EkI+4v5cv4q9YThy/dJl3Rc3Ef6fjTNZqrQYlU+TAA3u 9liFpp84wUNN0/a9decuIaGn9gD6wt+2cDdy1tN/+QXrGEh1N3LMy0dH78b0naQyOznEek bn1+Uv5tQ5e9U73yvuzn3Rxesl5iacD97I6ioWXA4SIza5IpvewoY9r7Xxi1viEq4+x4uq vQSAu9HtcpBM7udhabhufKdCSDesikX/cp36xunbN3xAVpRv4xzLe39A9gV5QvNEWMArVf yxlAWXLiLMJ1muty22Acenyd8DLZtVUe0WK3Bhg8IEgSqQTaFn1iO79kq/5c6w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gRzT90p8NztjN for ; Fri, 29 May 2026 23:04:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 42494 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 29 May 2026 23:04:45 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dimitry Andric Subject: git: 2e97bf202703 - stable/14 - Merge commit c1d26c3c2510 from llvm git (by Nikolas Klauser): List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: dim X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 2e97bf202703413b4d6e5bce080f9d511886fc97 Auto-Submitted: auto-generated Date: Fri, 29 May 2026 23:04:45 +0000 Message-Id: <6a1a1b8d.42494.48334f06@gitrepo.freebsd.org> The branch stable/14 has been updated by dim: URL: https://cgit.FreeBSD.org/src/commit/?id=2e97bf202703413b4d6e5bce080f9d511886fc97 commit 2e97bf202703413b4d6e5bce080f9d511886fc97 Author: Dimitry Andric AuthorDate: 2026-03-12 13:24:01 +0000 Commit: Dimitry Andric CommitDate: 2026-05-29 22:59:37 +0000 Merge commit c1d26c3c2510 from llvm git (by Nikolas Klauser): [libc++] Fix iostream size ABI break (#185839) In #124103 we changed the size of various iostream objects, which turns out to be ABI breaking when compiling non-PIE code. This ABI break is safe to fix, since for any programs allocating more memory for the iostream objects, the remaining bytes are simply unused now. Fixes #185724 This fixes the ABI break that causes programs that use the standard streams to terminate in various interesting ways, usually by throwing an unexpected std::bad_cast exception. PR: 292067 MFC after: 1 month (cherry picked from commit 4fc1fdd206c3db60ca521e3966f31044c7711398) --- contrib/llvm-project/libcxx/src/iostream.cpp | 93 +++++++++++++++++----------- 1 file changed, 56 insertions(+), 37 deletions(-) diff --git a/contrib/llvm-project/libcxx/src/iostream.cpp b/contrib/llvm-project/libcxx/src/iostream.cpp index 416725235c34..b216c6ad35da 100644 --- a/contrib/llvm-project/libcxx/src/iostream.cpp +++ b/contrib/llvm-project/libcxx/src/iostream.cpp @@ -16,24 +16,40 @@ _LIBCPP_BEGIN_NAMESPACE_STD +// This file implements the various stream objects provided inside . We're doing some ODR violations in here, +// so this quite fragile. Specifically, the size of the stream objects (i.e. cout, cin etc.) needs to stay the same. +// For that reason, we have `stream` and `stream_data` separated into two objects. The public `stream` objects only +// contain the actual stream, while the private `stream_data` objects contains the `basic_streambuf` we're using as well +// as the mbstate_t. `stream_data` objects are only accessible within the library, so they aren't ABI sensitive and we +// can change them as we want. + +template +union stream { + constexpr stream() {} + stream(const stream&) = delete; + stream& operator=(const stream&) = delete; + constexpr ~stream() {} + + StreamT value; +}; + template union stream_data { constexpr stream_data() {} constexpr ~stream_data() {} struct { - // The stream has to be the first element, since that's referenced by the stream declarations in - StreamT stream; BufferT buffer; mbstate_t mb; }; - - void init(FILE* stdstream) { - mb = {}; - std::construct_at(&buffer, stdstream, &mb); - std::construct_at(&stream, &buffer); - } }; +template +void init_stream(FILE* stdstream, stream& stream, stream_data& data) { + data.mb = {}; + std::construct_at(&data.buffer, stdstream, &data.mb); + std::construct_at(&stream.value, &data.buffer); +} + #define CHAR_MANGLING_char "D" #define CHAR_MANGLING_wchar_t "_W" #define CHAR_MANGLING(CharT) CHAR_MANGLING_##CharT @@ -46,25 +62,28 @@ union stream_data { #ifdef _LIBCPP_ABI_MICROSOFT # define STREAM(StreamT, BufferT, CharT, var) \ - STRING_DATA_CONSTINIT stream_data, BufferT> var __asm__( \ + STRING_DATA_CONSTINIT stream_data, BufferT> var##_data; \ + _LIBCPP_EXPORTED_FROM_ABI STRING_DATA_CONSTINIT stream> var __asm__( \ "?" #var "@" ABI_NAMESPACE_STR "@std@@3V?$" #StreamT \ "@" CHAR_MANGLING(CharT) "U?$char_traits@" CHAR_MANGLING(CharT) "@" ABI_NAMESPACE_STR "@std@@@12@A") #else -# define STREAM(StreamT, BufferT, CharT, var) STRING_DATA_CONSTINIT stream_data, BufferT> var +# define STREAM(StreamT, BufferT, CharT, var) \ + STRING_DATA_CONSTINIT stream_data, BufferT> var##_data; \ + _LIBCPP_EXPORTED_FROM_ABI STRING_DATA_CONSTINIT stream> var #endif // These definitions and the declarations in technically cause ODR violations, since they have different // types (stream_data and {i,o}stream respectively). This means that should never be included in this TU. -_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_istream, __stdinbuf, char, cin); -_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, cout); -_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, cerr); -_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, char, clog); +STREAM(basic_istream, __stdinbuf, char, cin); +STREAM(basic_ostream, __stdoutbuf, char, cout); +STREAM(basic_ostream, __stdoutbuf, char, cerr); +STREAM(basic_ostream, __stdoutbuf, char, clog); #if _LIBCPP_HAS_WIDE_CHARACTERS -_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_istream, __stdinbuf, wchar_t, wcin); -_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wcout); -_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wcerr); -_LIBCPP_EXPORTED_FROM_ABI STREAM(basic_ostream, __stdoutbuf, wchar_t, wclog); +STREAM(basic_istream, __stdinbuf, wchar_t, wcin); +STREAM(basic_ostream, __stdoutbuf, wchar_t, wcout); +STREAM(basic_ostream, __stdoutbuf, wchar_t, wcerr); +STREAM(basic_ostream, __stdoutbuf, wchar_t, wclog); #endif // _LIBCPP_HAS_WIDE_CHARACTERS // Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority @@ -98,34 +117,34 @@ public: DoIOSInit::DoIOSInit() { force_locale_initialization(); - cin.init(stdin); - cout.init(stdout); - cerr.init(stderr); - clog.init(stderr); + init_stream(stdin, cin, cin_data); + init_stream(stdout, cout, cout_data); + init_stream(stderr, cerr, cerr_data); + init_stream(stderr, clog, clog_data); - cin.stream.tie(&cout.stream); - std::unitbuf(cerr.stream); - cerr.stream.tie(&cout.stream); + cin.value.tie(&cout.value); + std::unitbuf(cerr.value); + cerr.value.tie(&cout.value); #if _LIBCPP_HAS_WIDE_CHARACTERS - wcin.init(stdin); - wcout.init(stdout); - wcerr.init(stderr); - wclog.init(stderr); - - wcin.stream.tie(&wcout.stream); - std::unitbuf(wcerr.stream); - wcerr.stream.tie(&wcout.stream); + init_stream(stdin, wcin, wcin_data); + init_stream(stdout, wcout, wcout_data); + init_stream(stderr, wcerr, wcerr_data); + init_stream(stderr, wclog, wclog_data); + + wcin.value.tie(&wcout.value); + std::unitbuf(wcerr.value); + wcerr.value.tie(&wcout.value); #endif } DoIOSInit::~DoIOSInit() { - cout.stream.flush(); - clog.stream.flush(); + cout.value.flush(); + clog.value.flush(); #if _LIBCPP_HAS_WIDE_CHARACTERS - wcout.stream.flush(); - wclog.stream.flush(); + wcout.value.flush(); + wclog.value.flush(); #endif }