public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/107919] New: Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types
@ 2022-11-29 16:29 freddie_chopin at op dot pl
  2022-11-29 16:48 ` [Bug tree-optimization/107919] " freddie_chopin at op dot pl
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: freddie_chopin at op dot pl @ 2022-11-29 16:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107919

            Bug ID: 107919
           Summary: Possibly false-positive "maybe-uninitialized" with GCC
                    12 on complex variant-variant-tuple-unique_ptr types
           Product: gcc
           Version: 12.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: freddie_chopin at op dot pl
  Target Milestone: ---

Following code gives no warning with GCC 11.3 and earlier versions:

-- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --

#include <memory>
#include <variant>

using Event = std::variant<std::variant<std::tuple<std::unique_ptr<int>>>, int,
char>;

void do_something(void* storage)
{
        Event event {};
        auto& swappedValue = *reinterpret_cast<Event*>(storage);
        std::swap(event, swappedValue);
}

-- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --

When compiled with GCC 12.1 or newer it reports a (possibly false-positive)
maybe-uninitialized warning that is so long, that it is hard to comprehend (;

-- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --

$ g++ -std=c++17 -c -O2 warn.cpp -Wall -Wextra
In file included from /usr/include/c++/12.2.0/bits/unique_ptr.h:36,
                 from /usr/include/c++/12.2.0/memory:76,
                 from warn.cpp:1:
In constructor ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail
...>::_Tuple_impl(std::_Tuple_impl<_Idx, _Head, _Tail ...>&&) [with long
unsigned int _Idx = 0; _Head = int*; _Tail = {std::default_delete<int>}]’,
    inlined from ‘constexpr std::tuple<_T1, _T2>::tuple(std::tuple<_T1, _T2>&&)
[with _T1 = int*; _T2 = std::default_delete<int>]’ at
/usr/include/c++/12.2.0/tuple:1090:17,
    inlined from ‘std::__uniq_ptr_impl<_Tp,
_Dp>::__uniq_ptr_impl(std::__uniq_ptr_impl<_Tp, _Dp>&&) [with _Tp = int; _Dp =
std::default_delete<int>]’ at /usr/include/c++/12.2.0/bits/unique_ptr.h:177:9,
    inlined from ‘std::__uniq_ptr_data<_Tp, _Dp, <anonymous>, <anonymous>
>::__uniq_ptr_data(std::__uniq_ptr_data<_Tp, _Dp, <anonymous>, <anonymous> >&&)
[with _Tp = int; _Dp = std::default_delete<int>; bool <anonymous> = true; bool
<anonymous> = true]’ at /usr/include/c++/12.2.0/bits/unique_ptr.h:234:7,
    inlined from ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp,
_Dp>&&) [with _Tp = int; _Dp = std::default_delete<int>]’ at
/usr/include/c++/12.2.0/bits/unique_ptr.h:358:7,
    inlined from ‘std::_Head_base<_Idx, _Head,
false>::_Head_base(std::_Head_base<_Idx, _Head, false>&&) [with long unsigned
int _Idx = 0; _Head = std::unique_ptr<int>]’ at
/usr/include/c++/12.2.0/tuple:196:17,
    inlined from ‘constexpr std::_Tuple_impl<_Idx,
_Head>::_Tuple_impl(std::_Tuple_impl<_Idx, _Head>&&) [with long unsigned int
_Idx = 0; _Head = std::unique_ptr<int>]’ at
/usr/include/c++/12.2.0/tuple:456:41,
    inlined from ‘constexpr std::tuple< <template-parameter-1-1>
>::tuple(std::tuple< <template-parameter-1-1> >&&) [with _Elements =
{std::unique_ptr<int, std::default_delete<int> >}]’ at
/usr/include/c++/12.2.0/tuple:756:17,
    inlined from ‘constexpr std::__detail::__variant::_Uninitialized<_Type,
false>::_Uninitialized(std::in_place_index_t<0>, _Args&& ...) [with _Args =
{std::tuple<std::unique_ptr<int, std::default_delete<int> > >}; _Type =
std::tuple<std::unique_ptr<int, std::default_delete<int> > >]’ at
/usr/include/c++/12.2.0/variant:283:4,
    inlined from ‘constexpr std::__detail::__variant::_Variadic_union<_First,
_Rest ...>::_Variadic_union(std::in_place_index_t<0>, _Args&& ...) [with _Args
= {std::tuple<std::unique_ptr<int, std::default_delete<int> > >}; _First =
std::tuple<std::unique_ptr<int, std::default_delete<int> > >; _Rest = {}]’ at
/usr/include/c++/12.2.0/variant:385:4,
    inlined from ‘void std::_Construct(_Tp*, _Args&& ...) [with _Tp =
__detail::__variant::_Variadic_union<tuple<unique_ptr<int, default_delete<int>
> > >; _Args = {const in_place_index_t<0>&, tuple<unique_ptr<int,
default_delete<int> > >}]’ at
/usr/include/c++/12.2.0/bits/stl_construct.h:119:7,
    inlined from ‘std::__detail::__variant::_Move_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::_Move_ctor_base(std::__detail::__variant::_Move_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>&&)::<lambda(auto:4&&, auto:5)> mutable [with auto:4 =
std::tuple<std::unique_ptr<int, std::default_delete<int> > >; auto:5 =
std::integral_constant<long unsigned int, 0>]’ at
/usr/include/c++/12.2.0/variant:605:23,
    inlined from ‘constexpr _Res std::__invoke_impl(__invoke_other, _Fn&&,
_Args&& ...) [with _Res = void; _Fn =
__detail::__variant::_Move_ctor_base<false, tuple<unique_ptr<int,
default_delete<int> > >
>::_Move_ctor_base(std::__detail::__variant::_Move_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>&&)::<lambda(auto:4&&, auto:5)>; _Args = {tuple<unique_ptr<int,
default_delete<int> > >, integral_constant<long unsigned int, 0>}]’ at
/usr/include/c++/12.2.0/bits/invoke.h:61:36,
    inlined from ‘constexpr typename std::__invoke_result<_Functor,
_ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable =
__detail::__variant::_Move_ctor_base<false, tuple<unique_ptr<int,
default_delete<int> > >
>::_Move_ctor_base(std::__detail::__variant::_Move_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>&&)::<lambda(auto:4&&, auto:5)>; _Args = {tuple<unique_ptr<int,
default_delete<int> > >, integral_constant<long unsigned int, 0>}]’ at
/usr/include/c++/12.2.0/bits/invoke.h:96:40,
    inlined from ‘static constexpr decltype(auto)
std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<_Result_type
(*)(_Visitor, _Variants ...)>, std::integer_sequence<long unsigned int,
__indices ...> >::__visit_invoke(_Visitor&&, _Variants ...) [with _Result_type
= std::__detail::__variant::__variant_idx_cookie; _Visitor =
std::__detail::__variant::_Move_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::_Move_ctor_base(std::__detail::__variant::_Move_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>&&)::<lambda(auto:4&&, auto:5)>&&; _Variants =
{std::variant<std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>&&}; long unsigned int ...__indices = {0}]’ at
/usr/include/c++/12.2.0/variant:1020:17,
    inlined from ‘constexpr decltype(auto) std::__do_visit(_Visitor&&,
_Variants&& ...) [with _Result_type =
__detail::__variant::__variant_idx_cookie; _Visitor =
__detail::__variant::_Move_ctor_base<false, tuple<unique_ptr<int,
default_delete<int> > >
>::_Move_ctor_base(std::__detail::__variant::_Move_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>&&)::<lambda(auto:4&&, auto:5)>; _Variants = {variant<tuple<unique_ptr<int,
default_delete<int> > > >}]’ at /usr/include/c++/12.2.0/variant:1783:5,
    inlined from ‘constexpr decltype(auto) std::__do_visit(_Visitor&&,
_Variants&& ...) [with _Result_type =
__detail::__variant::__variant_idx_cookie; _Visitor =
__detail::__variant::_Move_ctor_base<false, tuple<unique_ptr<int,
default_delete<int> > >
>::_Move_ctor_base(std::__detail::__variant::_Move_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>&&)::<lambda(auto:4&&, auto:5)>; _Variants = {variant<tuple<unique_ptr<int,
default_delete<int> > > >}]’ at /usr/include/c++/12.2.0/variant:1729:5,
    inlined from ‘constexpr void
std::__detail::__variant::__raw_idx_visit(_Visitor&&, _Variants&& ...) [with
_Visitor = _Move_ctor_base<false, std::tuple<std::unique_ptr<int,
std::default_delete<int> > >
>::_Move_ctor_base(std::__detail::__variant::_Move_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>&&)::<lambda(auto:4&&, auto:5)>; _Variants =
{std::variant<std::tuple<std::unique_ptr<int, std::default_delete<int> > > >}]’
at /usr/include/c++/12.2.0/variant:184:44,
    inlined from ‘std::__detail::__variant::_Move_ctor_base<<anonymous>,
_Types>::_Move_ctor_base(std::__detail::__variant::_Move_ctor_base<<anonymous>,
_Types>&&) [with bool <anonymous> = false; _Types =
{std::tuple<std::unique_ptr<int, std::default_delete<int> > >}]’ at
/usr/include/c++/12.2.0/variant:600:28,
    inlined from ‘std::__detail::__variant::_Copy_assign_base<<anonymous>,
_Types>::_Copy_assign_base(std::__detail::__variant::_Copy_assign_base<<anonymous>,
_Types>&&) [with bool <anonymous> = false; _Types =
{std::tuple<std::unique_ptr<int, std::default_delete<int> > >}]’ at
/usr/include/c++/12.2.0/variant:665:7,
    inlined from ‘std::__detail::__variant::_Move_assign_base<<anonymous>,
_Types>::_Move_assign_base(std::__detail::__variant::_Move_assign_base<<anonymous>,
_Types>&&) [with bool <anonymous> = false; _Types =
{std::tuple<std::unique_ptr<int, std::default_delete<int> > >}]’ at
/usr/include/c++/12.2.0/variant:719:7,
    inlined from
‘std::__detail::__variant::_Variant_base<_Types>::_Variant_base(std::__detail::__variant::_Variant_base<_Types>&&)
[with _Types = {std::tuple<std::unique_ptr<int, std::default_delete<int> > >}]’
at /usr/include/c++/12.2.0/variant:750:7,
    inlined from ‘std::variant<_Types>::variant(std::variant<_Types>&&) [with
_Types = {std::tuple<std::unique_ptr<int, std::default_delete<int> > >}]’ at
/usr/include/c++/12.2.0/variant:1404:7,
    inlined from ‘void std::_Construct(_Tp*, _Args&& ...) [with _Tp =
variant<tuple<unique_ptr<int, default_delete<int> > > >; _Args =
{variant<tuple<unique_ptr<int, default_delete<int> > > >}]’ at
/usr/include/c++/12.2.0/bits/stl_construct.h:119:7,
    inlined from ‘void
std::__detail::__variant::__emplace(_Variant_storage<_Triv, _Types ...>&,
_Args&& ...) [with long unsigned int _Np = 0; bool _Triv = false; _Types =
{std::variant<std::tuple<std::unique_ptr<int, std::default_delete<int> > > >,
int, char}; _Args = {std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >}]’ at /usr/include/c++/12.2.0/variant:541:22,
    inlined from ‘std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int,
char>::swap(std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int, char>&)::<lambda(auto:22&&, auto:23)>
mutable [with auto:22 = std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >&; auto:23 = std::integral_constant<long unsigned
int, 0>]’ at /usr/include/c++/12.2.0/variant:1650:32,
    inlined from ‘constexpr _Res std::__invoke_impl(__invoke_other, _Fn&&,
_Args&& ...) [with _Res = void; _Fn = variant<variant<tuple<unique_ptr<int,
default_delete<int> > > >, int,
char>::swap(std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int, char>&)::<lambda(auto:22&&, auto:23)>;
_Args = {variant<tuple<unique_ptr<int, default_delete<int> > > >&,
integral_constant<long unsigned int, 0>}]’ at
/usr/include/c++/12.2.0/bits/invoke.h:61:36,
    inlined from ‘constexpr typename std::__invoke_result<_Functor,
_ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable =
variant<variant<tuple<unique_ptr<int, default_delete<int> > > >, int,
char>::swap(std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int, char>&)::<lambda(auto:22&&, auto:23)>;
_Args = {variant<tuple<unique_ptr<int, default_delete<int> > > >&,
integral_constant<long unsigned int, 0>}]’ at
/usr/include/c++/12.2.0/bits/invoke.h:96:40,
    inlined from ‘static constexpr decltype(auto)
std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<_Result_type
(*)(_Visitor, _Variants ...)>, std::integer_sequence<long unsigned int,
__indices ...> >::__visit_invoke(_Visitor&&, _Variants ...) [with _Result_type
= std::__detail::__variant::__variant_idx_cookie; _Visitor =
std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int,
char>::swap(std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int, char>&)::<lambda(auto:22&&, auto:23)>&&;
_Variants = {std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int, char>&}; long unsigned int ...__indices =
{0}]’ at /usr/include/c++/12.2.0/variant:1020:17,
    inlined from ‘constexpr decltype(auto) std::__do_visit(_Visitor&&,
_Variants&& ...) [with _Result_type =
__detail::__variant::__variant_idx_cookie; _Visitor =
variant<variant<tuple<unique_ptr<int, default_delete<int> > > >, int,
char>::swap(std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int, char>&)::<lambda(auto:22&&, auto:23)>;
_Variants = {variant<variant<tuple<unique_ptr<int, default_delete<int> > > >,
int, char>&}]’ at /usr/include/c++/12.2.0/variant:1783:5,
    inlined from ‘constexpr decltype(auto) std::__do_visit(_Visitor&&,
_Variants&& ...) [with _Result_type =
__detail::__variant::__variant_idx_cookie; _Visitor =
variant<variant<tuple<unique_ptr<int, default_delete<int> > > >, int,
char>::swap(std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int, char>&)::<lambda(auto:22&&, auto:23)>;
_Variants = {variant<variant<tuple<unique_ptr<int, default_delete<int> > > >,
int, char>&}]’ at /usr/include/c++/12.2.0/variant:1729:5,
    inlined from ‘constexpr void
std::__detail::__variant::__raw_idx_visit(_Visitor&&, _Variants&& ...) [with
_Visitor = std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int,
char>::swap(std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int, char>&)::<lambda(auto:22&&, auto:23)>;
_Variants = {std::variant<std::variant<std::tuple<std::unique_ptr<int,
std::default_delete<int> > > >, int, char>&}]’ at
/usr/include/c++/12.2.0/variant:184:44,
    inlined from ‘void std::variant<_Types>::swap(std::variant<_Types>&) [with
_Types = {std::variant<std::tuple<std::unique_ptr<int, std::default_delete<int>
> > >, int, char}]’ at /usr/include/c++/12.2.0/variant:1623:28,
    inlined from ‘std::enable_if_t<((is_move_constructible_v<_Types> && ...) &&
(is_swappable_v<_Types> && ...))> std::swap(variant<_Types ...>&,
variant<_Types ...>&) [with _Types = {variant<tuple<unique_ptr<int,
default_delete<int> > > >, int, char}]’ at
/usr/include/c++/12.2.0/variant:1297:17,
    inlined from ‘void do_something(void*)’ at warn.cpp:10:11:
/usr/include/c++/12.2.0/tuple:301:7: warning: ‘*(int**)((char*)&__tmp +
offsetof(std::variant<std::tuple<std::unique_ptr<int, std::default_delete<int>
> > >,std::variant<std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Variant_base<std::tuple<std::unique_ptr<int,
std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Move_assign_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Copy_assign_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Move_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Copy_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Variant_storage<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > > >::_M_u))’ may be
used uninitialized [-Wmaybe-uninitialized]
  301 |       _Tuple_impl(_Tuple_impl&&) = default;
      |       ^~~~~~~~~~~
In file included from warn.cpp:2:
/usr/include/c++/12.2.0/variant: In function ‘void do_something(void*)’:
/usr/include/c++/12.2.0/variant:1636:26: note: ‘*(int**)((char*)&__tmp +
offsetof(std::variant<std::tuple<std::unique_ptr<int, std::default_delete<int>
> > >,std::variant<std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Variant_base<std::tuple<std::unique_ptr<int,
std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Move_assign_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Copy_assign_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Move_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Copy_ctor_base<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > >
>::<unnamed>.std::__detail::__variant::_Variant_storage<false,
std::tuple<std::unique_ptr<int, std::default_delete<int> > > >::_M_u))’ was
declared here
 1636 |                     auto __tmp(std::move(__rhs_mem));
      |                          ^~~~~

-- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --

Above warning is with GCC 12.2 on PC (linux), but I also get a similar (or
identical, hard to see) warning for 12.1 (tested for arm-none-eabi target, as I
have multiple versions of the compiler at hand).

It seems as if any change in the test-case above will make the warning go away,
even changes which should not make much difference - for example reducing the
number of types in the "outer" variant from 3 to 2 or just putting the "complex
type" inside a struct or renaming `Event` to sth else and creating a struct
called `Event` which inherits the "complex type". But things like avoiding the
tuple, avoiding unique_ptr, avoiding variant-in-variant - each one makes the
warning disappear. Also using a "real" object instead of casted `void*` storage
"solves" the problem, however this particular code is part of a low-level
embedded RTOS and I would really prefer to keep using `void*` in this case. But
as I mentioned, even with casted `void*` but slightly simpler/different `Event`
type, the warning is gone.

Note - having optional-in-variant also produces mostly identical warning.

I'm not sure whether this is intended behavior and my code is indeed wrong or
maybe this is a regression.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107919] Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types
  2022-11-29 16:29 [Bug c++/107919] New: Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types freddie_chopin at op dot pl
@ 2022-11-29 16:48 ` freddie_chopin at op dot pl
  2022-11-30  9:12 ` rguenth at gcc dot gnu.org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: freddie_chopin at op dot pl @ 2022-11-29 16:48 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107919

--- Comment #1 from Freddie Chopin <freddie_chopin at op dot pl> ---
More possibly imporant notes:
1. The warning appears only with -O1 or -O2, with 0, s, g or 3 the warning is
gone.
2. Adding -fsanitize=undefined to compiler invocation makes the warning go away
as well - no terminal output is produced in that case.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107919] Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types
  2022-11-29 16:29 [Bug c++/107919] New: Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types freddie_chopin at op dot pl
  2022-11-29 16:48 ` [Bug tree-optimization/107919] " freddie_chopin at op dot pl
@ 2022-11-30  9:12 ` rguenth at gcc dot gnu.org
  2022-11-30 10:59 ` rguenth at gcc dot gnu.org
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-11-30  9:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107919

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
             Blocks|                            |24639
   Last reconfirmed|                            |2022-11-30
             Status|UNCONFIRMED                 |NEW

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Confirmed on trunk.  Hmm,

After normalization [USE]:
        MEM[(struct _Tuple_impl *)this_5(D)] = __tmp_653;
  is conditional on:
        ((_109 == 0))

After normalization [DEF]:
        __tmp_653 = PHI <__tmp_652(44), __tmp_652(98), __tmp_365(91)>
  is conditional on: 
        ((_145 != 0B) AND (_531 == 2) AND (_109 == 0))
        OR ((NOT (_145 != 0B)) AND (_531 == 2) AND (_109 == 0))
        OR ((NOT (_531 == 2)) AND (_109 == 0))

the former conservatively describes the domain the use happens on while
the latter conservatively describes the domain the definition is
initialized.

We try to compute whether the initialized domain is a superset of the
use domain and compute that to be false.

I think that's misleading in the way that we fail to take into account
a conservative predicate that the definition is reached at all here,
that is, we prune the predicate that the domain of the use at the
definition.

There's the missing simplification

 A && B || !A && B

to B in the DEF domain predicate and reducing it to a single
(_531 == 2) && (_109 == 0).  That wouldn't help on its own, we still
have the domain constraint _531 == 2 that's not on the USE domain predicate.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639
[Bug 24639] [meta-bug] bug to track all Wuninitialized issues

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107919] Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types
  2022-11-29 16:29 [Bug c++/107919] New: Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types freddie_chopin at op dot pl
  2022-11-29 16:48 ` [Bug tree-optimization/107919] " freddie_chopin at op dot pl
  2022-11-30  9:12 ` rguenth at gcc dot gnu.org
@ 2022-11-30 10:59 ` rguenth at gcc dot gnu.org
  2022-11-30 11:01 ` cvs-commit at gcc dot gnu.org
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-11-30 10:59 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107919

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot gnu.org
             Status|NEW                         |ASSIGNED

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ah, implementing the existing simplification properly fixes this, but only at
-O1.  At -O2 we have

        ((_277 == 2) AND (_79 == 0))
        OR ((NOT (_277 == 0)) AND (NOT (_277 > 2)) AND (NOT (_277 == 2)) AND
(_79 == 0))
        OR ((NOT (pretmp_300 == 255)) AND (_277 == 0) AND (NOT (_277 > 2)) AND
(NOT (_277 == 2)) AND (_79 == 0))

and

        ((_79 == 0))

and more upthread (the CFG is much more complicated).  In the above predicate
one can at least see

 (_277 == 0) AND (NOT (_277 > 2))  ->  (_277 == 0)

 (NOT (_277 > 2)) AND (NOT (_277 == 2)) -> (_277 < 2)

 (NOT (_277 > 2)) -> (_277 <= 2)  (might make !A vs. A more difficult)

kind of simplification opportunities.  The above doesn't seem to be the
predicate to simplify in the end though.

Implementing some of these simplifies this to

        ((_79 == 0) AND (_277 == 2))
        OR ((_79 == 0) AND (_277 <= 1) AND (NOT (_277 == 0)))
        OR ((_79 == 0) AND (_277 == 0) AND (NOT (pretmp_300 == 255)))

there's

  _84 = MEM[(const struct variant
*)this_69].D.41415.D.40957.D.40877.D.40745.D.40631.D.40535._M_index; 
  _115 = (signed char) _84;
  _277 = (long unsigned int) _115;

and

  pretmp_300 = MEM[(const struct _Variant_storage *)this_69]._M_index;

with pretmp_300 being unsigned char and _84 the same, so pretmp_300
and _277 are related and (_277 == 0) && !(pretmp_300 == 255) should
simplify to (_277 == 0) which really should make the last two
predicates to collapse(?) and then the rest to a single

  ((_79 == 0) AND (_277 <= 2)

?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107919] Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types
  2022-11-29 16:29 [Bug c++/107919] New: Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types freddie_chopin at op dot pl
                   ` (2 preceding siblings ...)
  2022-11-30 10:59 ` rguenth at gcc dot gnu.org
@ 2022-11-30 11:01 ` cvs-commit at gcc dot gnu.org
  2022-11-30 11:01 ` rguenth at gcc dot gnu.org
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-11-30 11:01 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107919

--- Comment #4 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:9500877d05c56cef7bfbdcecaab3b1af2610bff3

commit r13-4406-g9500877d05c56cef7bfbdcecaab3b1af2610bff3
Author: Richard Biener <rguenther@suse.de>
Date:   Wed Nov 30 10:55:03 2022 +0100

    tree-optimization/107919 - uninit diagnostic predicate simplification

    We fail to simplify

            ((_145 != 0B) AND (_531 == 2) AND (_109 == 0))
            OR ((NOT (_145 != 0B)) AND (_531 == 2) AND (_109 == 0))
            OR ((NOT (_531 == 2)) AND (_109 == 0))

    because the existing simplification of !A && B || A && B is implemented
    too simplistic.  The following re-implements that which fixes the
    bogus uninit diagnostic when using -O1 but not yet at -O2.

            PR tree-optimization/107919
            * gimple-predicate-analysis.cc (predicate::simplify_2):
            Handle predicates of arbitrary length.

            * g++.dg/warn/Wuninitialized-pr107919-1.C: New testcase.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107919] Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types
  2022-11-29 16:29 [Bug c++/107919] New: Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types freddie_chopin at op dot pl
                   ` (3 preceding siblings ...)
  2022-11-30 11:01 ` cvs-commit at gcc dot gnu.org
@ 2022-11-30 11:01 ` rguenth at gcc dot gnu.org
  2022-11-30 11:53 ` cvs-commit at gcc dot gnu.org
  2024-05-16  7:48 ` rguenth at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-11-30 11:01 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107919

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
Fixed at -O1, still mis-diagnosed at -O2.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107919] Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types
  2022-11-29 16:29 [Bug c++/107919] New: Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types freddie_chopin at op dot pl
                   ` (4 preceding siblings ...)
  2022-11-30 11:01 ` rguenth at gcc dot gnu.org
@ 2022-11-30 11:53 ` cvs-commit at gcc dot gnu.org
  2024-05-16  7:48 ` rguenth at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-11-30 11:53 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107919

--- Comment #6 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:b628cad9e093f7a33042fb9dd647f183394eefae

commit r13-4408-gb628cad9e093f7a33042fb9dd647f183394eefae
Author: Richard Biener <rguenther@suse.de>
Date:   Wed Nov 30 12:05:29 2022 +0100

    tree-optimization/107919 - predicate simplification in uninit

    The testcase from the PR at -O2 shows

        ((_277 == 2) AND (_79 == 0))
        OR ((NOT (_277 == 0)) AND (NOT (_277 > 2)) AND (NOT (_277 == 2)) AND
(_79 == 0))
        OR ((NOT (pretmp_300 == 255)) AND (_277 == 0) AND (NOT (_277 > 2)) AND
(NOT (_277 == 2)) AND (_79 == 0))

    which we fail to simplify.  The following patch makes us simplify
    the relations on _277, producing

        ((_79 == 0) AND (_277 == 2))
        OR ((_79 == 0) AND (_277 <= 1) AND (NOT (_277 == 0)))
        OR ((_79 == 0) AND (_277 == 0) AND (NOT (pretmp_300 == 255)))

    which might be an incremental step to resolve a bogus uninit
    diagnostic at -O2.  The patch uses maybe_fold_and_comparison for this.

            PR tree-optimization/107919
            * gimple-predicate-analysis.cc (simplify_1): Rename to ...
            (simplify_1a): .. this.
            (simplify_1b): New.
            (predicate::simplify): Call both simplify_1a and simplify_1b.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug tree-optimization/107919] Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types
  2022-11-29 16:29 [Bug c++/107919] New: Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types freddie_chopin at op dot pl
                   ` (5 preceding siblings ...)
  2022-11-30 11:53 ` cvs-commit at gcc dot gnu.org
@ 2024-05-16  7:48 ` rguenth at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-05-16  7:48 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107919

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|---                         |13.0
         Resolution|---                         |FIXED
      Known to work|                            |13.1.0, 14.1.0
      Known to fail|                            |12.3.0
             Status|ASSIGNED                    |RESOLVED

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
With GCC 13 and newer we also do not diagnose with -O2 or -O3.  I have a patch
for trunk (GCC 15) that's going to regress for -O1 (but not -O2 or -O3),
still declaring this fixed as reported.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-05-16  7:48 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-29 16:29 [Bug c++/107919] New: Possibly false-positive "maybe-uninitialized" with GCC 12 on complex variant-variant-tuple-unique_ptr types freddie_chopin at op dot pl
2022-11-29 16:48 ` [Bug tree-optimization/107919] " freddie_chopin at op dot pl
2022-11-30  9:12 ` rguenth at gcc dot gnu.org
2022-11-30 10:59 ` rguenth at gcc dot gnu.org
2022-11-30 11:01 ` cvs-commit at gcc dot gnu.org
2022-11-30 11:01 ` rguenth at gcc dot gnu.org
2022-11-30 11:53 ` cvs-commit at gcc dot gnu.org
2024-05-16  7:48 ` rguenth at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).