-
Notifications
You must be signed in to change notification settings - Fork 13.3k
tuple variant crashing iterating over vector with std::apply (clang 17.0.1 - clang 19.1.0) #126246
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
Comments
Doesn't reproduce on Clang thunk. Please wait for Clang 20 release.
You can visit cppreference to see how |
@llvm/issue-subscribers-clang-frontend Author: None (wh1t3lord)
## Problem
Here's a function that fills a std::vector<std::variant<Ts...>> from a std::vector<std::string_view>. The function template takes a std::tuple<Ts...> as a type parameter and uses std::apply to iterate over the tuple's types. It attempts to convert each string in the input vector to the corresponding type or keeps it as a string if conversion is not possible. Code & Proof#include <iostream>
#include <vector>
#include <variant>
#include <tuple>
#include <string_view>
#include <cstdlib> // for std::atoi, std::atof
#include <type_traits>
template <typename... Ts>
std::vector<std::variant<Ts...>> fill_vector(const std::vector<std::string_view>& input) {
using VariantType = std::variant<Ts...>;
std::vector<VariantType> result;
result.reserve(input.size());
for (const auto& str : input) {
bool converted = false;
// Create a temporary tuple to pass to std::apply
std::tuple<Ts...> tempTuple;
std::apply([&](auto&&... args) {
// Fold expression to try each type
(([&] {
using T = std::decay_t<decltype(args)>;
if (!converted) {
if constexpr (std::is_integral_v<T>) {
try {
result.emplace_back(static_cast<T>(std::atoi(str.data())));
converted = true;
} catch (...) {}
} else if constexpr (std::is_floating_point_v<T>) {
try {
result.emplace_back(static_cast<T>(std::atof(str.data())));
converted = true;
} catch (...) {}
}
}
}()), ...);
}, tempTuple);
if (!converted) {
result.emplace_back(std::string(str)); // Fallback to string
}
}
return result;
}
int main() {
std::vector<std::string_view> input = {"123", "45.67", "hello", "789"};
auto output = fill_vector<int, double, std::string>(input);
for (const auto& v : output) {
std::visit([](const auto& value) { std::cout << value << " "; }, v);
}
return 0;
}
Proof №1: https://godbolt.org/z/TPv4vcGch (clang 17.0.1) Proof №2: https://godbolt.org/z/178zP4x9v (clang 19.1.0) So both crashes. Working sample (Expected behaviour)Unexpected but it compiles on gcc. Link: https://godbolt.org/z/W8jqWqzE3 (gcc 12.1) Link: https://godbolt.org/z/n9GWG4EM8 (gcc 14.2) Crash backtraceProceed to godbolt site with attached link in previous section. |
As a workaround you can inline the type-alias into the template arugments: https://godbolt.org/z/P57q6h7os |
Problem
Here's a function that fills a std::vector<std::variant<Ts...>> from a std::vectorstd::string_view. The function template takes a std::tuple<Ts...> as a type parameter and uses std::apply to iterate over the tuple's types. It attempts to convert each string in the input vector to the corresponding type or keeps it as a string if conversion is not possible.
Code & Proof
Proof №1: https://godbolt.org/z/TPv4vcGch (clang 17.0.1)
Proof №2: https://godbolt.org/z/178zP4x9v (clang 19.1.0)
So both crashes.
Working sample (Expected behaviour)
Unexpected but it compiles on gcc.
Link: https://godbolt.org/z/W8jqWqzE3 (gcc 12.1)
Link: https://godbolt.org/z/n9GWG4EM8 (gcc 14.2)
Crash backtrace
Proceed to godbolt site with attached link in previous section.
The text was updated successfully, but these errors were encountered: