[libc++][format] Fixes constexpr validation.
authorMark de Wever <koraq@xs4all.nl>
Mon, 6 Feb 2023 15:29:30 +0000 (16:29 +0100)
committerMark de Wever <koraq@xs4all.nl>
Tue, 7 Feb 2023 14:57:04 +0000 (15:57 +0100)
The constexpr validation parsed parts of the format string that didn't
belong to the specific replacement field.

Fixes https://llvm.org/PR60536

Reviewed By: #libc, ldionne

Differential Revision: https://reviews.llvm.org/D143402

libcxx/include/__format/format_functions.h
libcxx/test/std/utilities/format/format.functions/format_tests.h

index 7589b63..ee05170 100644 (file)
@@ -261,10 +261,12 @@ __handle_replacement_field(_Iterator __begin, _Iterator __end,
 
   if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) {
     __arg_t __type = __ctx.arg(__r.__value);
-    if (__type == __arg_t::__handle)
+    if (__type == __arg_t::__none)
+      std::__throw_format_error("Argument index out of bounds");
+    else if (__type == __arg_t::__handle)
       __ctx.__handle(__r.__value).__parse(__parse_ctx);
-    else
-        __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
+    else if (__parse)
+      __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
   } else
     _VSTD::__visit_format_arg(
         [&](auto __arg) {
index 86d11f2..763cf45 100644 (file)
@@ -2617,6 +2617,10 @@ void format_tests(TestFunction check, ExceptionTest check_exception) {
 
   check(SV("{"), SV("{{"));
   check(SV("}"), SV("}}"));
+  check(SV("{:^}"), SV("{{:^}}"));
+  check(SV("{: ^}"), SV("{{:{}^}}"), CharT(' '));
+  check(SV("{:{}^}"), SV("{{:{{}}^}}"));
+  check(SV("{:{ }^}"), SV("{{:{{{}}}^}}"), CharT(' '));
 
   // *** Test argument ID ***
   check(SV("hello false true"), SV("hello {0:} {1:}"), false, true);