On Tue, Nov 17, 2020 at 01:33:48AM -0500, Jason Merrill via Gcc-patches wrote:
> > > Why doesn't the middle-end warning work for inline functions?
> > 
> > It does but only when they're called (and, as usual, also unless
> > the uninitialized use is eliminated).
> 
> Yes, but why?  I assume because we don't bother going through all the phases
> of compilation for unused inlines, but couldn't we change that when we're
> asking for (certain) warnings?

CCing Richard and Honza on this.

I think for unused functions we don't even gimplify unused functions, the
cgraph code just throws them away.  Even trying just to run the first few
passes (gimplification up to uninit1) would have several high costs,
the tree body of everything unneeded would be unshared, reemitted as GIMPLE,
then cfg created for it and turned into SSA form only to get the
uninitialized warnings (for that warning we could stop there and throw the
bodies away).
I think we would need to try that on some larger C++ codebases and see what
the compile time memory and time hit would be.

Anyway, taking e.g. Marek's Wuninitialized-17.C testcase, if I add
S s;
at the end to make the S::S() ctor used, uninit1 does warn
(guess many of the warnings would be dependent on -flifetime-dse=2
inserted CLOBBERs, thankfully that is the default), but the warnings then
look fairly cryptic:
Wuninitialized-17.C: In constructor ‘S::S()’:
Wuninitialized-17.C:22:14: warning: ‘*<unknown>.S::y’ is used uninitialized 
[-Wuninitialized]
   22 |   S() : a{1, y} { } // { dg-warning "field .S::y. is used 
uninitialized" }
      |              ^
Guess we should at least try to improve this special case's printing for C++, 
the IL
is:
  *this_3(D) ={v} {CLOBBER};
  this_3(D)->a.a = 1;
  _1 = this_3(D)->y;
  this_3(D)->a.b = _1;
and we could figure out that this is in a METHOD_TYPE fndecl, the MEM_REF
has as address the default def of this SSA_NAME where this is the first
argument of the method and the PARM_DECL has this name and is
DECL_ARTIFICIAL to print it as this->S::y instead of *<unknown>.S::y.
I bet that code is in error.c ...

If the costs of gimplifying, creating cfg and SSA form for all functions
would be too high (I think it would be, but haven't measured it), then
perphaps it might be useful for Marek's FE code to handle the easiest cases
and punt when it gets more complicated?
I mean e.g. the a(b=1) cases, or can't e.g. some member be initialized only
in some other function - a (foo (&b)) where foo would store to what the
pointer points to (or reference refers to)?

        Jakub

Reply via email to