On Wed, 3 Apr 2019 10:18:35 +0200 Santiago Vila <sanv...@unex.es> wrote: > On Tue, Apr 02, 2019 at 10:57:39PM +0300, Коля Гурьев wrote: > > Control: forwarded -1 https://github.com/ericniebler/range-v3/issues/856 > > Hi. I believe this one (failure with GCC 9) could be a bit closer: > > https://github.com/ericniebler/range-v3/issues/1033 > > Thanks. >
Hi, This issue doesn't seem related to that github issue. I've investigated the cause of the warning inside gcc. (I'm not accustomed to gcc internals so some of my sentences might be imprecise :)) While debugging cc1plus, I found that the warning is caused for this GIMPLE instruction: ``` [../include/range/v3/utility/counted_iterator.hpp:291:18] # VUSE <.MEM_335> _293 = MEM[(long int *)[../test/container_conversion.cpp:48:4] &D.184479 + 8B]; ``` (note that D.184479 number changes every-time I run gcc) The GIMPLE dump can be generated using `-fdump-tree-uninit-vops-lineno`. The dump is somewhat complicated to read but here is my analysis. The warning is triggered by the first statement in container_conversion.hpp [0]. `view::ints | view::take(10)` has the type take_really. It is converted to a std::vector via `operator std::vector<int>` which is implemented as a template inside view_interface [1]. That operator call to_ which end up calling to_container_fn::impl [2] which will itself call std::vector::assign [3] and std::vector::_M_assign_aux [4]. When calling std::vector::assign, to_container_fn::impl create begin and end iterators with range_common_iterator_t [5]. This will create `common_iterator`s which is really a variant with the real underlying iterator (of type counted_iterator) and the sentinel type. Then, when gcc search for uninitialized cases, it find a case when: - the __last iterator is the sentinel - there is a use of the __last iterator as a counted_iterator with an access to its cnt_ field In that case, gcc think the underlying storage of the variant is not initialized as the sentinel is an empty structure which is true. But then the of the cnt_ field is not used later. See here for the GIMPLE dump: [6]. The codepath leading to the uninitialized use of D.184248 imply that iftmp.47_15 != 0. But the codepath leading to a use of the uninitialized value D.184248 require iftmp.47_15 == 0. Indeed, MEM[(long int *)&D.184248 + 8B] is used via _293 and _279 in if conditions in blocks bb 13 and bb 18 which are executed only if iftmp.47_15 == 0. If that's the case, bb 3 would be executed at the start of the function and bb 3 initialize MEM[(struct Head *)&D.167417] (so including initialization of MEM[(long int *)&D.184248 + 8B]). Thus, this maybe-uninitialized warning is a false positive. By search for bugs in gcc about false positive, I found that this is not a rare case. I suggest to make this warning not trigger an error for the build. We could use `-Wno-error=maybe-uninitialized` but cc1plus does not recognize some of the command line arguments and as soon as it print a diagnostic message (the maybe-uninitialized warning), it also print errors about unrecognized arguments. This make the build still fail. Maybe there is a -Wno-error=XXX to make unrecognized command line arguments not an error too. Or we can use `-Wno-maybe-uninitialized` which works but is maybe too much radical. [0] https://sources.debian.org/src/range-v3/0.4.0-1/test/container_conversion.cpp/#L39 [1] https://sources.debian.org/src/range-v3/0.4.0-1/include/range/v3/view_interface.hpp/#L370 [2] https://sources.debian.org/src/range-v3/0.4.0-1/include/range/v3/to_container.hpp/#L147 [3] https://sources.debian.org/src/range-v3/0.4.0-1/include/range/v3/to_container.hpp/#L84 [4] https://github.com/gcc-mirror/gcc/blob/gcc-8_3_0-release/libstdc++-v3/include/bits/vector.tcc#L271 [5] https://sources.debian.org/src/range-v3/0.4.0-1/include/range/v3/to_container.hpp/#L83 [6] https://gist.github.com/amurzeau/ca58f3ebe890371a295d8f2537fa09cc#file-container_conversion-cpp-197t-uninit1-cpp-L230 -- Alexis Murzeau PGP: B7E6 0EBB 9293 7B06 BDBC 2787 E7BD 1904 F480 937F
signature.asc
Description: OpenPGP digital signature