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

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to