Skip to content

[libc++] Implements Runtime format strings. #73353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 9, 2023

Conversation

mordante
Copy link
Member

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

@mordante mordante requested a review from a team as a code owner November 24, 2023 17:23
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Nov 24, 2023
@llvmbot
Copy link
Member

llvmbot commented Nov 24, 2023

@llvm/pr-subscribers-libcxx

Author: Mark de Wever (mordante)

Changes

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

Patch is 20.89 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73353.diff

20 Files Affected:

  • (modified) libcxx/docs/ReleaseNotes/18.rst (+1)
  • (modified) libcxx/docs/Status/Cxx2cPapers.csv (+1-1)
  • (modified) libcxx/docs/Status/FormatIssues.csv (+1-1)
  • (modified) libcxx/include/__format/format_arg_store.h (+3-3)
  • (modified) libcxx/include/__format/format_functions.h (+2-2)
  • (modified) libcxx/include/format (+2-2)
  • (modified) libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp (+4-2)
  • (modified) libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.sh.cpp (+6-2)
  • (modified) libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.sh.cpp (+6-2)
  • (modified) libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.pass.cpp (+6-2)
  • (modified) libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.sh.cpp (+2-1)
  • (added) libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.verify.cpp (+19)
  • (modified) libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_wformat_args.pass.cpp (+6-2)
  • (added) libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_wformat_args.verify.cpp (+20)
  • (modified) libcxx/test/std/utilities/format/format.arguments/format.args/ctad.compile.pass.cpp (+3-2)
  • (modified) libcxx/test/std/utilities/format/format.arguments/format.args/ctor.pass.cpp (+6-3)
  • (modified) libcxx/test/std/utilities/format/format.formatter/format.context/format.context/arg.pass.cpp (+4-2)
  • (modified) libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp (+4-1)
  • (modified) libcxx/test/std/utilities/format/format.formatter/format.context/format.context/locale.pass.cpp (+4-1)
  • (modified) libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.string.pass.cpp (+1-2)
diff --git a/libcxx/docs/ReleaseNotes/18.rst b/libcxx/docs/ReleaseNotes/18.rst
index 946e9bf42475f65..fdab0ef0d29b1a0 100644
--- a/libcxx/docs/ReleaseNotes/18.rst
+++ b/libcxx/docs/ReleaseNotes/18.rst
@@ -50,6 +50,7 @@ Implemented Papers
 - P0053R7 - C++ Synchronized Buffered Ostream (in the experimental library)
 - P2467R1 - Support exclusive mode for fstreams
 - P0020R6 - Floating Point Atomic
+- P2905R2 - Runtime format strings
 - P2918R2 - Runtime format strings II
 - P2871R3 - Remove Deprecated Unicode Conversion Facets from C++26
 
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 5e413dec59d79af..fd875a6eeeafd19 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -30,7 +30,7 @@
 "`P0543R3 <https://wg21.link/P0543R3>`__","LWG","Saturation arithmetic","Kona November 2023","","",""
 "`P2407R5 <https://wg21.link/P2407R5>`__","LWG","Freestanding Library: Partial Classes","Kona November 2023","","",""
 "`P2546R5 <https://wg21.link/P2546R5>`__","LWG","Debugging Support","Kona November 2023","","",""
-"`P2905R2 <https://wg21.link/P2905R2>`__","LWG","Runtime format strings","Kona November 2023","","","|format| |DR|"
+"`P2905R2 <https://wg21.link/P2905R2>`__","LWG","Runtime format strings","Kona November 2023","|Complete|","18.0","|format| |DR|"
 "`P2918R2 <https://wg21.link/P2918R2>`__","LWG","Runtime format strings II","Kona November 2023","|Complete|","18.0","|format|"
 "`P2909R4 <https://wg21.link/P2909R4>`__","LWG","Fix formatting of code units as integers (Dude, where’s my ``char``?)","Kona November 2023","","","|format| |DR|"
 "`P0952R2 <https://wg21.link/P0952R2>`__","LWG","A new specification for ``std::generate_canonical``","Kona November 2023","","",""
diff --git a/libcxx/docs/Status/FormatIssues.csv b/libcxx/docs/Status/FormatIssues.csv
index 14ea7c4360a373f..b3a9be31046935b 100644
--- a/libcxx/docs/Status/FormatIssues.csv
+++ b/libcxx/docs/Status/FormatIssues.csv
@@ -17,7 +17,7 @@ Number,Name,Standard,Assignee,Status,First released version
 "`P2510R3 <https://wg21.link/P2510R3>`__","Formatting pointers","C++26","Mark de Wever","|Complete|",17.0
 "`P2757R3 <https://wg21.link/P2757R3>`__","Type-checking format args","C++26","","",
 "`P2637R3 <https://wg21.link/P2637R3>`__","Member ``visit``","C++26","","",
-"`P2905R2 <https://wg21.link/P2905R2>`__","Runtime format strings","C++26 DR","Mark de Wever","|In Progress|"
+"`P2905R2 <https://wg21.link/P2905R2>`__","Runtime format strings","C++26 DR","Mark de Wever","|Complete|",18.0
 "`P2918R2 <https://wg21.link/P2918R2>`__","Runtime format strings II","C++26","Mark de Wever","|Complete|",18.0
 "`P2909R4 <https://wg21.link/P2909R4>`__","Fix formatting of code units as integers (Dude, where’s my ``char``?)","C++26 DR","Mark de Wever","|In Progress|"
 `P1361 <https://wg21.link/P1361>`_,"Integration of chrono with text formatting","C++20",Mark de Wever,|In Progress|,
diff --git a/libcxx/include/__format/format_arg_store.h b/libcxx/include/__format/format_arg_store.h
index 15ec8eb0a7d838b..155694a19ca904b 100644
--- a/libcxx/include/__format/format_arg_store.h
+++ b/libcxx/include/__format/format_arg_store.h
@@ -202,8 +202,8 @@ _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp& __valu
 }
 
 template <class _Context, class... _Args>
-_LIBCPP_HIDE_FROM_ABI void __create_packed_storage(uint64_t& __types, __basic_format_arg_value<_Context>* __values,
-                                                   _Args&&... __args) noexcept {
+_LIBCPP_HIDE_FROM_ABI void
+__create_packed_storage(uint64_t& __types, __basic_format_arg_value<_Context>* __values, _Args&... __args) noexcept {
   int __shift = 0;
   (
       [&] {
@@ -220,7 +220,7 @@ _LIBCPP_HIDE_FROM_ABI void __create_packed_storage(uint64_t& __types, __basic_fo
 }
 
 template <class _Context, class... _Args>
-_LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>* __data, _Args&&... __args) noexcept {
+_LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>* __data, _Args&... __args) noexcept {
   ([&] { *__data++ = __format::__create_format_arg<_Context>(__args); }(), ...);
 }
 
diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h
index d4d36d68a98cc23..f3bd57bd7615340 100644
--- a/libcxx/include/__format/format_functions.h
+++ b/libcxx/include/__format/format_functions.h
@@ -63,14 +63,14 @@ using wformat_args = basic_format_args<wformat_context>;
 #endif
 
 template <class _Context = format_context, class... _Args>
-_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) {
+_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&... __args) {
   return _VSTD::__format_arg_store<_Context, _Args...>(__args...);
 }
 
 #  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <class... _Args>
 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...>
-make_wformat_args(_Args&&... __args) {
+make_wformat_args(_Args&... __args) {
   return _VSTD::__format_arg_store<wformat_context, _Args...>(__args...);
 }
 #  endif
diff --git a/libcxx/include/format b/libcxx/include/format
index 7b8d5922cb4971e..ab9b336d0cdabee 100644
--- a/libcxx/include/format
+++ b/libcxx/include/format
@@ -177,10 +177,10 @@ namespace std {
 
   template<class Context = format_context, class... Args>
     format-arg-store<Context, Args...>
-      make_format_args(Args&&... args);
+      make_format_args(Args&... args);
   template<class... Args>
     format-arg-store<wformat_context, Args...>
-      make_wformat_args(Args&&... args);
+      make_wformat_args(Args&... args);
 
   // [format.error], class format_error
   class format_error;
diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp
index c9297318cd5d667..f502616b677b776 100644
--- a/libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp
@@ -69,7 +69,8 @@ static void test_vprint_unicode() {
   FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
   assert(file);
 
-  std::vprint_unicode(file, "hello world{}", std::make_format_args('!'));
+  char c = '!';
+  std::vprint_unicode(file, "hello world{}", std::make_format_args(c));
   long pos = std::ftell(file);
   std::fclose(file);
 
@@ -83,7 +84,8 @@ static void test_vprint_nonunicode() {
   FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
   assert(file);
 
-  std::vprint_nonunicode(file, "hello world{}", std::make_format_args('!'));
+  char c = '!';
+  std::vprint_nonunicode(file, "hello world{}", std::make_format_args(c));
   long pos = std::ftell(file);
   std::fclose(file);
 
diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.sh.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.sh.cpp
index 63e1d2ad82b74e2..c1a690f559b11e3 100644
--- a/libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.sh.cpp
+++ b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.sh.cpp
@@ -35,8 +35,12 @@
 
 int main(int, char**) {
   // The data is passed as-is so it does not depend on the encoding of the input.
-  std::vprint_nonunicode("{} {} ", std::make_format_args(1234, "一二三四"));
-  std::vprint_nonunicode("{} {}", std::make_format_args(true, nullptr));
+  int i         = 1234;
+  const char* s = "一二三四";
+  bool b        = true;
+  nullptr_t p   = nullptr;
+  std::vprint_nonunicode("{} {} ", std::make_format_args(i, s));
+  std::vprint_nonunicode("{} {}", std::make_format_args(b, p));
 
   return 0;
 }
diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.sh.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.sh.cpp
index a9bcc33d2e014ac..198e71b55d9beb3 100644
--- a/libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.sh.cpp
+++ b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.sh.cpp
@@ -35,8 +35,12 @@
 
 int main(int, char**) {
   // The data is passed as-is so it does not depend on the encoding of the input.
-  std::vprint_unicode("{} {} ", std::make_format_args(1234, "一二三四"));
-  std::vprint_unicode("{} {}", std::make_format_args(true, nullptr));
+  int i         = 1234;
+  const char* s = "一二三四";
+  bool b        = true;
+  nullptr_t p   = nullptr;
+  std::vprint_unicode("{} {} ", std::make_format_args(i, s));
+  std::vprint_unicode("{} {}", std::make_format_args(b, p));
 
   return 0;
 }
diff --git a/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.pass.cpp b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.pass.cpp
index 72184bbd3920a74..a22660f1feea901 100644
--- a/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.pass.cpp
@@ -10,7 +10,7 @@
 // <format>
 
 // template<class Context = format_context, class... Args>
-// format-arg-store<Context, Args...> make_format_args(const Args&... args);
+// format-arg-store<Context, Args...> make_format_args(Args&... args);
 
 #include <cassert>
 #include <format>
@@ -21,7 +21,11 @@
 #include "test_macros.h"
 
 int main(int, char**) {
-  [[maybe_unused]] auto store = std::make_format_args(42, nullptr, false, 'x');
+  int i                       = 1;
+  char c                      = 'c';
+  nullptr_t p                 = nullptr;
+  bool b                      = false;
+  [[maybe_unused]] auto store = std::make_format_args(i, p, b, c);
 
   LIBCPP_STATIC_ASSERT(
       std::same_as<decltype(store), std::__format_arg_store<std::format_context, int, nullptr_t, bool, char>>);
diff --git a/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.sh.cpp b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.sh.cpp
index 95a94b0bff5d07b..2d5ee8349b749ff 100644
--- a/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.sh.cpp
+++ b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.sh.cpp
@@ -24,6 +24,7 @@
 #include "test_macros.h"
 
 void test() {
+  char c = 'c';
   TEST_IGNORE_NODISCARD
-  std::make_format_args<std::basic_format_context<std::back_insert_iterator<std::basic_string<wchar_t>>, wchar_t>>('c');
+  std::make_format_args<std::basic_format_context<std::back_insert_iterator<std::basic_string<wchar_t>>, wchar_t>>(c);
 }
diff --git a/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.verify.cpp b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.verify.cpp
new file mode 100644
index 000000000000000..7bd9cb54f8aef1c
--- /dev/null
+++ b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_format_args.verify.cpp
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <format>
+
+// template<class... Args>
+//   format-arg-store<format_context, Args...>
+//   make_format_args(const Args&... args);
+
+#include <format>
+
+// expected-error@*:* {{no matching function for call to 'make_format_args'}}
+[[maybe_unused]] auto store = std::make_format_args(42);
diff --git a/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_wformat_args.pass.cpp b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_wformat_args.pass.cpp
index 22c6f031efc6f71..4afbf6d7d4d253f 100644
--- a/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_wformat_args.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_wformat_args.pass.cpp
@@ -12,7 +12,7 @@
 
 // template<class... Args>
 //   format-arg-store<wformat_context, Args...>
-//   make_wformat_args(const Args&... args);
+//   make_wformat_args(Args&... args);
 
 #include <cassert>
 #include <format>
@@ -21,7 +21,11 @@
 #include "test_macros.h"
 
 int main(int, char**) {
-  [[maybe_unused]] auto store = std::make_wformat_args(42, nullptr, false, 'x');
+  int i                       = 1;
+  char c                      = 'c';
+  nullptr_t p                 = nullptr;
+  bool b                      = false;
+  [[maybe_unused]] auto store = std::make_wformat_args(i, p, b, c);
 
   LIBCPP_STATIC_ASSERT(
       std::same_as<decltype(store), std::__format_arg_store<std::wformat_context, int, nullptr_t, bool, char>>);
diff --git a/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_wformat_args.verify.cpp b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_wformat_args.verify.cpp
new file mode 100644
index 000000000000000..c5f4bdfe0c726f9
--- /dev/null
+++ b/libcxx/test/std/utilities/format/format.arguments/format.arg.store/make_wformat_args.verify.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-wide-characters
+
+// <format>
+
+// template<class... Args>
+//   format-arg-store<wformat_context, Args...>
+//   make_wformat_args(const Args&... args);
+
+#include <format>
+
+// expected-error@*:* {{no matching function for call to 'make_wformat_args'}}
+[[maybe_unused]] auto store = std::make_wformat_args(42);
diff --git a/libcxx/test/std/utilities/format/format.arguments/format.args/ctad.compile.pass.cpp b/libcxx/test/std/utilities/format/format.arguments/format.args/ctad.compile.pass.cpp
index 7cadd4e76c74e0f..b87b5c774ef7e7b 100644
--- a/libcxx/test/std/utilities/format/format.arguments/format.args/ctad.compile.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.arguments/format.args/ctad.compile.pass.cpp
@@ -18,12 +18,13 @@
 #include "test_macros.h"
 
 void test() {
+  int i = 1;
   // Note the Standard way to create a format-arg-store is by using make_format_args.
-  static_assert(std::same_as<decltype(std::basic_format_args(std::make_format_args(42))),
+  static_assert(std::same_as<decltype(std::basic_format_args(std::make_format_args(i))),
                              std::basic_format_args<std::format_context>>);
 
 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
-  static_assert(std::same_as<decltype(std::basic_format_args(std::make_wformat_args(42))),
+  static_assert(std::same_as<decltype(std::basic_format_args(std::make_wformat_args(i))),
                              std::basic_format_args<std::wformat_context>>);
 
 #endif
diff --git a/libcxx/test/std/utilities/format/format.arguments/format.args/ctor.pass.cpp b/libcxx/test/std/utilities/format/format.arguments/format.args/ctor.pass.cpp
index c2d2d19d978bbd1..c0575c545bde31f 100644
--- a/libcxx/test/std/utilities/format/format.arguments/format.args/ctor.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.arguments/format.args/ctor.pass.cpp
@@ -20,6 +20,9 @@
 
 template <class CharT>
 void test() {
+  int i         = 1;
+  char c        = 'c';
+  nullptr_t p   = nullptr;
   using Context = std::basic_format_context<CharT*, CharT>;
   {
     ASSERT_NOEXCEPT(std::basic_format_args<Context>{});
@@ -28,14 +31,14 @@ void test() {
     assert(!format_args.get(0));
   }
   {
-    auto store = std::make_format_args<Context>(1);
+    auto store = std::make_format_args<Context>(i);
     ASSERT_NOEXCEPT(std::basic_format_args<Context>{store});
     std::basic_format_args<Context> format_args{store};
     assert(format_args.get(0));
     assert(!format_args.get(1));
   }
   {
-    auto store = std::make_format_args<Context>(1, 'c');
+    auto store = std::make_format_args<Context>(i, c);
     ASSERT_NOEXCEPT(std::basic_format_args<Context>{store});
     std::basic_format_args<Context> format_args{store};
     assert(format_args.get(0));
@@ -43,7 +46,7 @@ void test() {
     assert(!format_args.get(2));
   }
   {
-    auto store = std::make_format_args<Context>(1, 'c', nullptr);
+    auto store = std::make_format_args<Context>(i, c, p);
     ASSERT_NOEXCEPT(std::basic_format_args<Context>{store});
     std::basic_format_args<Context> format_args{store};
     assert(format_args.get(0));
diff --git a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/arg.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/arg.pass.cpp
index 153f8bbaa4b37f8..824813d33a519a3 100644
--- a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/arg.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/arg.pass.cpp
@@ -23,9 +23,11 @@
 
 template <class OutIt, class CharT>
 void test() {
+  bool b                          = true;
+  CharT c                         = CharT('a');
+  int a                           = 42;
   std::basic_string<CharT> string = MAKE_STRING(CharT, "string");
-  auto store = std::make_format_args<std::basic_format_context<OutIt, CharT>>(
-      true, CharT('a'), 42, string);
+  auto store                      = std::make_format_args<std::basic_format_context<OutIt, CharT>>(b, c, a, string);
   std::basic_format_args args = store;
 
   std::basic_string<CharT> output;
diff --git a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp
index 5f2f6f1ae370ccb..4a5b5b773ce7549 100644
--- a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp
@@ -36,11 +36,14 @@
 
 template <class OutIt, class CharT>
 void test() {
+  int a                           = 42;
+  bool b                          = true;
+  CharT c                         = CharT('a');
   std::basic_string<CharT> string = MAKE_STRING(CharT, "string");
   // The type of the object is an exposition only type. The temporary is needed
   // to extend the lifetype of the object since args stores a pointer to the
   // data in this object.
-  auto format_arg_store = std::make_format_args<std::basic_format_context<OutIt, CharT>>(true, CharT('a'), 42, string);
+  auto format_arg_store       = std::make_format_args<std::basic_format_context<OutIt, CharT>>(b, c, a, string);
   std::basic_format_args args = format_arg_store;
 
   {
diff --git a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/locale.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/locale.pass.cpp
index edb0a01dc7b0b8e..8e0819037774abb 100644
--- a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/locale.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/locale.pass.cpp
@@ -34,7 +34,10 @@ void test() {
   // The type of the object is an exposition only type. The temporary is needed
   // to extend the lifetype of the object since args stores a pointer to the
   // data in this object.
-  auto format_arg_store = std::make_format_args<std::basic_format_context<OutIt, CharT>>(true, CharT('a'), 42, string);
+  int a                       = 42;
+  bool b                      = true;
+  CharT c                     = CharT('a');
+  auto format_arg_store       = std::make_format_args<std::basic_format_context<OutIt, CharT>>(b, c, a, string);
   std::basic_format_args args = format_arg_store;
 
   {
diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.s...
[truncated]

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with a few small comments.

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
@mordante mordante force-pushed the GH-runtime_format_strings branch from f0ec89e to fda02a3 Compare December 8, 2023 16:59
@mordante mordante merged commit e3f154d into llvm:main Dec 9, 2023
@mordante mordante deleted the GH-runtime_format_strings branch December 9, 2023 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants