From ac44dadcbea52e14aab20c0d590d4ec00d615a93 Mon Sep 17 00:00:00 2001 From: Mark de Wever Date: Mon, 6 Feb 2023 16:29:30 +0100 Subject: [PATCH] [libc++][format] Fixes constexpr validation. 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 | 8 +++++--- libcxx/test/std/utilities/format/format.functions/format_tests.h | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h index 7589b63..ee05170 100644 --- a/libcxx/include/__format/format_functions.h +++ b/libcxx/include/__format/format_functions.h @@ -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) { diff --git a/libcxx/test/std/utilities/format/format.functions/format_tests.h b/libcxx/test/std/utilities/format/format.functions/format_tests.h index 86d11f2..763cf45 100644 --- a/libcxx/test/std/utilities/format/format.functions/format_tests.h +++ b/libcxx/test/std/utilities/format/format.functions/format_tests.h @@ -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); -- 2.7.4