Bug#1133642: taskflow: ftbfs with GCC-16
Christopher Obbard <[email protected]> Sun, 02 Aug 2026 17:03:27 +0100
| Newsgroups | gmane.linux.debian.devel.bugs.rc |
|---|---|
| Message-ID | <[email protected]> |
Hi Emanuele, On Mon, 13 Apr 2026 15:11:35 +0200 Emanuele Rocca <[email protected]> wrote: > Package: src:taskflow > Version: 3.9.0+ds-1 > Severity: important > Tags: sid forky ftbfs > User: [email protected] > Usertags: ftbfs-gcc-16 > > Hi, > > taskflow fails to build in a test rebuild on at least amd64 and arm64 with > gcc-16/g++-16, but builds properly with gcc-15/g++-15. Thanks for the report; this now appears to cause autoremovals for lots of packages and I saw no one has replied so thought I'd take a look. I've tracked this down and it isn't a bug in taskflow; it appears to be a regression in libstdc++ 16. Now I am no compiler expert so please take what I say with a pinch of salt. The no-init overload std::inclusive_scan(first, last, result, binary_op) initialises its accumulator by moving out of the first element of the input range: auto __init = _GLIBCXX_ITER_MOVE(__first); // was: auto __init = *__first; That happens unconditionally, so a plain out-of-place scan silently destroys the caller's input. For a value type with a destructive move (e.g. std::string) the first element is left empty. A reduced testcase, which fails with g++ 16 and passes with g++ 15 in both -std=c++17 and -std=c++20: #include <numeric> #include <string> #include <vector> #include <functional> #include <cassert> int main() { std::vector<std::string> in{"a", "b"}, out(2); std::inclusive_scan(in.begin(), in.end(), out.begin(), std::plus<std::string>{}); assert(out[1] == "ab"); // ok assert(in[0] == "a"); // fails: in[0] is an empty moved-from string } Passing in.cbegin()/in.cend() instead leaves the input intact, so the behaviour depends on the constness of the iterators handed in which is a good sign it wasn't intended. I believe it's non-conforming: [inclusive.scan]/6 specifies the effects purely as assignments through result + K, and /9 permits result == first as an aliasing allowance rather than as licence to modify the input when result != first. The move came in with gcc commit df1d436 ("libstdc++: Fix <numeric> parallel algos for move-only values [PR117905]"), which relaxed the requirement on the value type from CopyConstructible to MoveConstructible; gcc 15 is unaffected. I've reported it upstream as GCC Bug 126604: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126604 Gentoo hit the same six failures with taskflow 3.10.0 (https://bugs.gentoo.org/961562) so updating to a newer upstream release won't help. This explains the failure set exactly: only the six InclusiveScan.string.* cases fail, because the overloads taking an init value never touch the input and the TransformInclusiveScan tests are int-only (a moved-from int keeps its value). The test itself is correct: it computes its golden vector with a perfectly ordinary out-of-place std::inclusive_scan and that call alone is enough to corrupt the input, so no change to the test source can make it pass legitimately while linked against libstdc++ 16. So my plan to resolve this bug is to skip those six tests in debian/rules, via ctest -E 'InclusiveScan\.string\.', with a comment pointing to the GCC bug, and to file a separate Debian bug against taskflow to track enabling those tests once libstdc++ 16 is fixed. I guess I need to open a separate Debian bug on gcc-16 where I can link to the upstream GCC bug report. What do you think? Cheers! Christopher Obbard