From fd75fd1467488f01c19be3e7b3fee4018ce7e9bc Mon Sep 17 00:00:00 2001
From: Justine Tunney <jtunney@gmail.com>
Date: Tue, 9 Jan 2024 09:51:59 -0800
Subject: [PATCH] Make std::pair trivial

---
 Makefile                                 |  1 +
 test/BUILD.mk                            |  1 +
 test/libcxx/BUILD.mk                     | 40 ++++++++++++++++++++++++
 test/libcxx/trivial_test.cc              | 29 +++++++++++++++++
 third_party/libcxx/__config              |  4 +--
 third_party/libcxxabi/cxa_personality.cc |  1 +
 6 files changed, 74 insertions(+), 2 deletions(-)
 create mode 100644 test/libcxx/BUILD.mk
 create mode 100644 test/libcxx/trivial_test.cc

diff --git a/Makefile b/Makefile
index 6e6897e26..0f29afafc 100644
--- a/Makefile
+++ b/Makefile
@@ -299,6 +299,7 @@ include libc/testlib/BUILD.mk
 include tool/viz/lib/BUILD.mk
 include tool/args/BUILD.mk
 include test/posix/BUILD.mk
+include test/libcxx/BUILD.mk
 include test/tool/args/BUILD.mk
 include third_party/linenoise/BUILD.mk
 include third_party/maxmind/BUILD.mk
diff --git a/test/BUILD.mk b/test/BUILD.mk
index 60b42cb80..db75515cc 100644
--- a/test/BUILD.mk
+++ b/test/BUILD.mk
@@ -5,5 +5,6 @@
 o/$(MODE)/test:	o/$(MODE)/test/dsp	\
 		o/$(MODE)/test/libc	\
 		o/$(MODE)/test/net	\
+		o/$(MODE)/test/libcxx	\
 		o/$(MODE)/test/posix	\
 		o/$(MODE)/test/tool
diff --git a/test/libcxx/BUILD.mk b/test/libcxx/BUILD.mk
new file mode 100644
index 000000000..17bf2897a
--- /dev/null
+++ b/test/libcxx/BUILD.mk
@@ -0,0 +1,40 @@
+#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
+#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
+
+PKGS += TEST_LIBCXX
+
+TEST_LIBCXX_FILES := $(wildcard test/libcxx/*)
+TEST_LIBCXX_SRCS = $(filter %.cc,$(TEST_LIBCXX_FILES))
+TEST_LIBCXX_OBJS = $(TEST_LIBCXX_SRCS:%.cc=o/$(MODE)/%.o)
+TEST_LIBCXX_COMS = $(TEST_LIBCXX_OBJS:%.o=%.com)
+TEST_LIBCXX_BINS = $(TEST_LIBCXX_COMS) $(TEST_LIBCXX_COMS:%=%.dbg)
+TEST_LIBCXX_CHECKS = $(TEST_LIBCXX_COMS:%=%.runs)
+TEST_LIBCXX_TESTS = $(TEST_LIBCXX_COMS:%=%.ok)
+
+TEST_LIBCXX_DIRECTDEPS =				\
+	LIBC_INTRIN					\
+	LIBC_NEXGEN32E					\
+	LIBC_RUNTIME					\
+	THIRD_PARTY_LIBCXX
+
+TEST_LIBCXX_DEPS :=					\
+	$(call uniq,$(foreach x,$(TEST_LIBCXX_DIRECTDEPS),$($(x))))
+
+o/$(MODE)/test/libcxx/libcxx.pkg:			\
+		$(TEST_LIBCXX_OBJS)			\
+		$(foreach x,$(TEST_LIBCXX_DIRECTDEPS),$($(x)_A).pkg)
+
+o/$(MODE)/test/libcxx/%.com.dbg:			\
+		$(TEST_LIBCXX_DEPS)			\
+		o/$(MODE)/test/libcxx/%.o		\
+		o/$(MODE)/test/libcxx/libcxx.pkg	\
+		$(CRT)					\
+		$(APE_NO_MODIFY_SELF)
+	@$(APELINK)
+
+$(TEST_LIBCXX_OBJS): private CCFLAGS += -fexceptions -frtti
+
+.PHONY: o/$(MODE)/test/libcxx
+o/$(MODE)/test/libcxx:					\
+		$(TEST_LIBCXX_BINS)			\
+		$(TEST_LIBCXX_CHECKS)
diff --git a/test/libcxx/trivial_test.cc b/test/libcxx/trivial_test.cc
new file mode 100644
index 000000000..35958df42
--- /dev/null
+++ b/test/libcxx/trivial_test.cc
@@ -0,0 +1,29 @@
+/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│
+│ vi: set et ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                             :vi │
+╞══════════════════════════════════════════════════════════════════════════════╡
+│ Copyright 2024 Justine Alexandra Roberts Tunney                              │
+│                                                                              │
+│ Permission to use, copy, modify, and/or distribute this software for         │
+│ any purpose with or without fee is hereby granted, provided that the         │
+│ above copyright notice and this permission notice appear in all copies.      │
+│                                                                              │
+│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
+│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
+│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
+│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
+│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
+│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
+│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
+│ PERFORMANCE OF THIS SOFTWARE.                                                │
+╚─────────────────────────────────────────────────────────────────────────────*/
+#include <type_traits>
+#include <utility>
+
+static_assert(std::is_trivially_copyable<int>::value);
+static_assert(std::is_trivially_copyable<const int>::value);
+static_assert(std::is_trivially_copyable<std::pair<int *, const int>>::value);
+static_assert(
+    std::is_trivially_copyable<std::pair<const int, const int>>::value);
+
+int main(int argc, char *argv[]) {
+}
diff --git a/third_party/libcxx/__config b/third_party/libcxx/__config
index f6fa0de3e..0194906ef 100644
--- a/third_party/libcxx/__config
+++ b/third_party/libcxx/__config
@@ -15,9 +15,9 @@
 #define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
 #define _LIBCPP_DISABLE_DEPRECATION_WARNINGS
 #define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION
+#define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
 #define _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
 #define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE
-#define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
 
 #if defined(_MSC_VER) && !defined(__clang__)
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -1428,7 +1428,7 @@ extern "C" _LIBCPP_FUNC_VIS  void __sanitizer_annotate_contiguous_container(
 //
 // Not all platforms support this, but it helps avoid fd-leaks on platforms that
 // do.
-#if defined(__BIONIC__)
+#if defined(__BIONIC__) || defined(__COSMOPOLITAN__)
 #  define _LIBCPP_FOPEN_CLOEXEC_MODE "e"
 #else
 #  define _LIBCPP_FOPEN_CLOEXEC_MODE
diff --git a/third_party/libcxxabi/cxa_personality.cc b/third_party/libcxxabi/cxa_personality.cc
index 625f1d359..38346323a 100644
--- a/third_party/libcxxabi/cxa_personality.cc
+++ b/third_party/libcxxabi/cxa_personality.cc
@@ -1196,6 +1196,7 @@ __cxa_call_unexpected(void* arg)
     }
     else
     {
+        ttypeIndex = 0; // TODO(jart): why?
         t_handler = std::get_terminate();
         u_handler = std::get_unexpected();
     }