[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2021-02-25 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Jakub Jelinek  changed:

   What|Removed |Added

Summary|[8/9/10/11 regression]  |[8/9/10 regression]
   |std::optional and bogus |std::optional and bogus
   |-Wmaybe-uninitialized   |-Wmaybe-uninitialized
   |warning |warning

--- Comment #62 from Jakub Jelinek  ---
Fixed on the trunk.

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-04-09 Thread lh_mouse at 126 dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

--- Comment #53 from Liu Hao  ---
For people who are not willing to turn off this warning:

This warning may be suppressed by introducing a volatile member in the union
that is used as the storage.

Using Martin Sebor's testcase, this look likes this:

```
  union {
T t;
char x[sizeof (T)];
volatile char dont_use;   // this silences such warnings.
  };
```

(the `sizeof (T)` thing is unnecessary, as the union will always have correct
size and alignment w/o it.)

Hope it helps.

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-03-17 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Jeffrey A. Law  changed:

   What|Removed |Added

   Assignee|jamborm at gcc dot gnu.org |law at redhat dot com

--- Comment #52 from Jeffrey A. Law  ---
ACK.  I guess I'll try to polish up the vr-values hack I was playing with.

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-03-17 Thread jamborm at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

--- Comment #51 from Martin Jambor  ---
(In reply to Andrew Pinski from comment #48)
> This should also work too:
> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
> index ea8594db193..83b1d981439 100644
> --- a/gcc/tree-sra.c
> +++ b/gcc/tree-sra.c
> @@ -2499,6 +2499,7 @@ analyze_access_subtree (struct access *root, struct
> access *parent,
>   For integral types this means the precision has to match.
>  Avoid assumptions based on the integral type kind, too.  */
>if (INTEGRAL_TYPE_P (root->type)
> + && TREE_CODE (root->type) != BOOLEAN_TYPE
>   && (TREE_CODE (root->type) != INTEGER_TYPE
>   || TYPE_PRECISION (root->type) != root->size)
>   /* But leave bitfield accesses alone.  */
> 
>  CUT 

Well, this re-introduces bug PR 52244 and makes the associated
testcase fail.  PR 52244 fix specifically aimed to disallow boolean
replacements.

(In reply to Jeffrey A. Law from comment #50)
> Reassigning to Martin Jambor since the real fix is to avoid creating the
> V_C_E in the first place.

I hoped that changing SRA to emit a NOP_EXPR instead of V_C_E would
help, but unfortunately it doesn't.  I've been looking at this for the
whole evening yesterday and ATM I do not see how I could avoid
conversion without reintroducing PR 52244 (in the general case - this
is another consequence of the fact that SRA is not flow sensitive).

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-03-05 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Jeffrey A. Law  changed:

   What|Removed |Added

   Assignee|law at redhat dot com  |jamborm at gcc dot 
gnu.org

--- Comment #50 from Jeffrey A. Law  ---
Reassigning to Martin Jambor since the real fix is to avoid creating the V_C_E
in the first place.

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-03-04 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|8.4 |8.5

--- Comment #49 from Jakub Jelinek  ---
GCC 8.4.0 has been released, adjusting target milestone.

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-03-02 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

--- Comment #48 from Andrew Pinski  ---
(In reply to Jeffrey A. Law from comment #47)
> Martin, yea, your patch does prevent creation of the V_C_E.  That in turn
> allows maybe_a$live_7 to be directly used in the conditional which in turn
> allows tree-ssa-uninit.c to realize the problematic path isn't runtime
> feasible and suppresses the warning.

This should also work too:
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index ea8594db193..83b1d981439 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2499,6 +2499,7 @@ analyze_access_subtree (struct access *root, struct
access *parent,
  For integral types this means the precision has to match.
 Avoid assumptions based on the integral type kind, too.  */
   if (INTEGRAL_TYPE_P (root->type)
+ && TREE_CODE (root->type) != BOOLEAN_TYPE
  && (TREE_CODE (root->type) != INTEGER_TYPE
  || TYPE_PRECISION (root->type) != root->size)
  /* But leave bitfield accesses alone.  */

 CUT 

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-03-02 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

--- Comment #47 from Jeffrey A. Law  ---
Martin, yea, your patch does prevent creation of the V_C_E.  That in turn
allows maybe_a$live_7 to be directly used in the conditional which in turn
allows tree-ssa-uninit.c to realize the problematic path isn't runtime feasible
and suppresses the warning.

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-02-28 Thread jamborm at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

--- Comment #46 from Martin Jambor  ---
(In reply to Jason Merrill from comment #45)
> 
> We SRA a bool field into a QItype variable and then think we need a VCE to
> get back to bool.  Could the SRA variable have type bool?

A semi-wild guess, would the following make SRA not invent the V_C_E (and do
what you want)?

diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 5561ea6f655..c3551b469f1 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2515,7 +2515,7 @@ analyze_access_subtree (struct access *root, struct
access *parent,
   /* Always create access replacements that cover the whole access.
  For integral types this means the precision has to match.
 Avoid assumptions based on the integral type kind, too.  */
-  if (INTEGRAL_TYPE_P (root->type)
+  if (false && INTEGRAL_TYPE_P (root->type)
  && (TREE_CODE (root->type) != INTEGER_TYPE
  || TYPE_PRECISION (root->type) != root->size)
  /* But leave bitfield accesses alone.  */

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-02-28 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

--- Comment #45 from Jason Merrill  ---
(In reply to Jeffrey A. Law from comment #44)
> I suspect in the context where SRA creates the V_C_E we don't have enough
> information to know that the range of the input object is constrained
> enough.  We base the decision solely on the types.

We SRA a bool field into a QItype variable and then think we need a VCE to get
back to bool.  Could the SRA variable have type bool?

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-02-28 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Jeffrey A. Law  changed:

   What|Removed |Added

   Assignee|unassigned at gcc dot gnu.org  |law at redhat dot com

--- Comment #44 from Jeffrey A. Law  ---
I suspect in the context where SRA creates the V_C_E we don't have enough
information to know that the range of the input object is constrained enough. 
We base the decision solely on the types.

By the time we get into the middle end we can follow the use-def chain to the
PHI and realize the source object only has two possible values at runtime and
we can optimize the V_C_E into a NOP_EXPR.

I've contacted Eric B. offline on the semantics of V_C_E.  I think the
agreement is in this kind of scenario we ought to be able to simplify it into a
NOP_EXPR which should be sufficient to eliminate the false positive.

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-02-26 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

--- Comment #43 from Jason Merrill  ---
(In reply to Jeffrey A. Law from comment #42)
> I suspect the V_C_E  inhibits tree-ssa-uninit.c code to avoid false
> positives.  If we know the range of the V_C_E operand is narrow enough that
> it fits into the type of the result of the V_C_E, could we optimize the
> V_C_E into a NOP_EXPR?   We'd then forward propagate away the NOP_EXPR and
> the result is something the suppression code in tree-ssa-uninit.c can
> analyze better.

Looks like the V_C_E comes from sra_modify_assign:

  if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
{
=>rhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
 rhs);

Here rhs (the scalar replacement variable) has unsigned QI type and lhs has
type bool.

Changing the type of 'live' to unsigned char avoids the V_C_E and thus indeed
the warning.  This also works with the libstdc++ optional.

This seems like an SRA problem with fields of type bool.

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-02-24 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Jeffrey A. Law  changed:

   What|Removed |Added

 CC||law at redhat dot com

--- Comment #42 from Jeffrey A. Law  ---
Jason, thanks for the testcase in c#41.  Here's the blocks of interest:

;;   basic block 5, loop depth 0
;;pred:   3
;;2
  # maybe_a$m_6 = PHI <_5(3), maybe_a$m_4(D)(2)>
  # maybe_a$4_7 = PHI <1(3), 0(2)>
:
  _8 = maybe_b.live;
  if (_8 != 0)
goto ; [0.00%]
  else
goto ; [0.00%]
;;succ:   6
;;7

;;   basic block 6, loop depth 0
;;pred:   5
  B::~B (_b.D.2512.m_item);
;;succ:   7

;;   basic block 7, loop depth 0
;;pred:   5
;;6
  maybe_b ={v} {CLOBBER};
  resx 3
;;succ:   8

;;   basic block 8, loop depth 0
;;pred:   7
:
  _9 = VIEW_CONVERT_EXPR(maybe_a$4_7);
  if (_9 != 0)
goto ; [0.00%]
  else
goto ; [0.00%]
;;succ:   9
;;10

I believe the complaint arises from the PHI in BB5  which is then used BB9.
Intuitively we can see that anytime BB5 is reached directly from BB2 we know
that BB8 will transfer control to BB10, avoiding the problematical use in BB9.

However, the form of the CFG is particularly difficult for forward threader to
handle.  BB5 is a join point.  We can only have one other block in the
threading path with side effects -- and unfortunately we have BB6 and BB7.  We
can fudge a bit on BB8 due to some work Alex did a couple years back, but
ultimately the forward threader isn't going to handle this.

The backwards threader supports multiple blocks with side effects, but there
can only be one path from the start to the destination.  2->5->6->7->8 and
2->5->7->8 makes two paths, so it gets rejected.  This is a limitation we
really should lift in the backwards threader.

I suspect the V_C_E  inhibits tree-ssa-uninit.c code to avoid false positives. 
If we know the range of the V_C_E operand is narrow enough that it fits into
the type of the result of the V_C_E, could we optimize the V_C_E into a
NOP_EXPR?   We'd then forward propagate away the NOP_EXPR and the result is
something the suppression code in tree-ssa-uninit.c can analyze better.





We can see that the path 2->5->6->7->8->9 is infeasible as is the path
2->5->7->8->9.  ANytime BB5 is reached directly from BB2

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-01-30 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

--- Comment #41 from Jason Merrill  ---
(In reply to Jason Merrill from comment #38)
> This is better:

Complete revised testcase:

#ifdef USE_STD

#include 
using std::optional;

#else

using size_t = decltype(sizeof(1));
inline void *operator new (size_t, void *p) { return p; }
template
struct optional
{
  optional () : m_dummy (), live (false) {}
  void emplace () { new (_item) T (); live = true; }
  ~optional () { if (live) m_item.~T (); }

  union
  {
struct {} m_dummy;
T m_item;
  };
  bool live;
};

#endif

extern int get ();
extern void set (int);

struct A
{
  A () : m (get ()) {}
  ~A () { set (m); }

  int m;
};

struct B
{
  B ();
  ~B ();
};

void func ()
{
  optional maybe_a;
  optional maybe_b;

  maybe_a.emplace ();
  maybe_b.emplace ();
}

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-01-30 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Jason Merrill  changed:

   What|Removed |Added

 CC||malcolm.parsons at gmail dot 
com

--- Comment #40 from Jason Merrill  ---
*** Bug 92194 has been marked as a duplicate of this bug. ***

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-01-30 Thread marxin at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Martin Liška  changed:

   What|Removed |Added

 CC||f.heckenb...@fh-soft.de

--- Comment #39 from Martin Liška  ---
*** Bug 92700 has been marked as a duplicate of this bug. ***

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-01-17 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Richard Biener  changed:

   What|Removed |Added

   Priority|P3  |P2
Version|unknown |8.2.0

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-01-17 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Richard Biener  changed:

   What|Removed |Added

   Target Milestone|--- |8.4

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-01-06 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

--- Comment #38 from Jason Merrill  ---
(In reply to Jason Merrill from comment #37)
>(because the warning is correct for the over-reduced optional):

This is better:

template
struct optional
{
  optional () : m_dummy (), live (false) {}
  void emplace () { new (_item) T (); live = true; }
  ~optional () { if (live) m_item.~T (); }

  union
  {
int m_dummy;
T m_item;
  };
  bool live;
};

[Bug tree-optimization/80635] [8/9/10 regression] std::optional and bogus -Wmaybe-uninitialized warning

2020-01-06 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635

Jason Merrill  changed:

   What|Removed |Added

  Component|c++ |tree-optimization
  Known to work||5.5.0
Summary|std::optional and bogus |[8/9/10 regression]
   |-Wmaybe-uninitialized   |std::optional and bogus
   |warning |-Wmaybe-uninitialized
   ||warning
  Known to fail||10.0, 6.5.0, 7.3.1, 8.3.1,
   ||9.2.1

--- Comment #37 from Jason Merrill  ---
Regression from GCC 5, because with the GCC 6 -flifetime-dse changes we
properly recognize the initial state of the object as uninitialized; with
-fno-lifetime-dse we think it starts out zero-initialized.

The problem is that we have two parallel variables that aren't being treated as
parallel.  From the .optimized dump of the comment 0 test using std::optional
(because the warning is correct for the over-reduced optional):

   [count: 0]:
  # maybe_a$m_51 = PHI  // _M_value
  # maybe_a$4_54 = PHI <0(2), 1(5)> // _M_engaged
...
  _12 = VIEW_CONVERT_EXPR(maybe_a$4_54);
  if (_12 != 0)
goto ; [0.00%]
  else
goto ; [0.00%]

   [count: 0]:
  set (maybe_a$m_51);

Here maybe_a$m_51 is uninitialized iff maybe_a$4_54 is 0, and in that case we
don't use the uninitialized value.  The PHIs are completely parallel.  I'm a
bit surprised the optimizer doesn't already handle this sort of situation,
where a conditional jump determines which PHI argument we have, and therefore
should be able to select the corresponding argument from parallel PHIs in the
target block.  So bb 10 should be

  set (_29);

and we shouldn't get the warning.