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

--- Comment #44 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jason Merrill from comment #40)
> (In reply to Richard Biener from comment #39)
> > so - how do I make X::X used and thus prevail?  It looks like it doesn't
> > really exist
> 
> True, for C++14 and up, "X x{};" does aggregate initialization rather than
> calling the constructor.  We ought to warn about this at function scope, but
> we clear the object first, so it isn't actually uninitialized.
> 
> As you found, removing the {} makes it use the constructor.
> 
> > OK, doing void foo() { X x; } shows
> > 
> > X::X (struct X * const this)
> > {
> >   _1 = this->x2;
> >   this->x1 = _1;
> >   this->x2 = 0;
> > }
> > 
> > foo ()
> > {
> >   struct X x;
> > 
> >   try
> >     {
> >       X::X (&x);
> >     }
> >   finally
> >     {
> >       x = {CLOBBER};
> >     }
> > }
> > 
> > warning would need inlining of the constructor which only happens after
> > the early warning pass, the late one isn't run at -O0 and with optimization
> > everything of course vanishes.
> 
> I was wondering about a maybe-uninitialized warning for the constructor
> without considering where it's called from; even if a particular object is
> zero-initialized when we enter the implicit constructor, the constructor
> shouldn't rely on that.  Basically, warn as if there were a clobber, without
> there actually being one.

Interesting suggestion but that's IMHO a bit too much information from
the outside to pack into the middle-end code.  That we're dealing with
accesses to *this and that we are inside a constructor.  You'd need to
add that here, tree-ssa-uninit.c:warn_uninitialized_vars

              /* Do not warn if it can be initialized outside this function.
                 If we did not reach function entry then we found killing
                 clobbers on all paths to entry.  */
              if (fentry_reached
                  /* ???  We'd like to use ref_may_alias_global_p but that
                     excludes global readonly memory and thus we get bougs
                     warnings from p = cond ? "a" : "b" for example.  */
                  && (!VAR_P (base)
                      || is_global_var (base)))
                continue;

given we have to constrain this to must-aliases of *this the easiest
check would be sth like

   && (!eligible-constructor (cfun)
       || TREE_CODE (base) != MEM_REF
       || TREE_OPERAND (base, 0) != default-def-of-this-parm))

and then elide the warning to maybe-uninit.  I guess we now have a flag
whether a function is a constructor and we also can get at the this
parm-decl so in theory "enhancing" the warning this way would be possible.

Reply via email to