Skip to content

Commit 167ec54

Browse files
committed
Report error on duplicate named arg names
#4282
1 parent 7f76955 commit 167ec54

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

include/fmt/base.h

+10
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,11 @@ void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
10711071
template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
10721072
void init_named_arg(named_arg_info<Char>* named_args, int& arg_index,
10731073
int& named_arg_index, const T& arg) {
1074+
for (auto i = 0; i < named_arg_index; ++i) {
1075+
if (basic_string_view<Char>(named_args[i].name) == basic_string_view<Char>(arg.name)) {
1076+
report_error("duplicate named args found");
1077+
}
1078+
}
10741079
named_args[named_arg_index++] = {arg.name, arg_index++};
10751080
}
10761081

@@ -1084,6 +1089,11 @@ template <typename T, typename Char,
10841089
FMT_ENABLE_IF(is_static_named_arg<T>::value)>
10851090
FMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>* named_args,
10861091
int& arg_index, int& named_arg_index) {
1092+
for (auto i = 0; i < named_arg_index; ++i) {
1093+
if (basic_string_view<Char>(named_args[i].name) == basic_string_view<Char>(T::name)) {
1094+
report_error("duplicate named args found");
1095+
}
1096+
}
10871097
named_args[named_arg_index++] = {T::name, arg_index++};
10881098
}
10891099

test/compile-error-test/CMakeLists.txt

+8
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,14 @@ if (CMAKE_CXX_STANDARD GREATER_EQUAL 20)
209209
#error
210210
#endif
211211
" ERROR)
212+
expect_compile(format-string-duplicate-name-error "
213+
#if defined(FMT_HAS_CONSTEVAL) && FMT_USE_NONTYPE_TEMPLATE_ARGS
214+
using namespace fmt::literals;
215+
fmt::print(\"{bar}\", \"bar\"_a=42, \"bar\"_a=43);
216+
#else
217+
#error
218+
#endif
219+
" ERROR)
212220
endif ()
213221

214222
# Run all tests

test/format-test.cc

+2
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,8 @@ TEST(format_test, named_arg) {
582582
EXPECT_EQ("1/a/A", fmt::format("{_1}/{a_}/{A_}", fmt::arg("a_", 'a'),
583583
fmt::arg("A_", "A"), fmt::arg("_1", 1)));
584584
EXPECT_EQ(fmt::format("{0:{width}}", -42, fmt::arg("width", 4)), " -42");
585+
EXPECT_THROW_MSG(fmt::format("{enum}", fmt::arg("enum", 1), fmt::arg("enum", 10)),
586+
format_error, "duplicate named args found");
585587
EXPECT_EQ("st",
586588
fmt::format("{0:.{precision}}", "str", fmt::arg("precision", 2)));
587589
EXPECT_EQ(fmt::format("{} {two}", 1, fmt::arg("two", 2)), "1 2");

0 commit comments

Comments
 (0)