This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/19808] miss a warning about uninitialized member usage in member initializer list in constructor
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 11 May 2018 07:04:30 +0000
- Subject: [Bug c++/19808] miss a warning about uninitialized member usage in member initializer list in constructor
- Auto-submitted: auto-generated
- References: <bug-19808-4@http.gcc.gnu.org/bugzilla/>
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.