On Mon, 2020-03-09 at 14:33 -0600, Martin Sebor wrote:
> On 3/5/20 5:26 PM, Jeff Law wrote:
> > On Fri, 2020-02-14 at 15:41 -0700, Martin Sebor wrote:
> > > Because attribute weakref introduces a kind of a definition, it can
> > > only be applied to declarations of symbols that are not defined.  GCC
> > > normally issues a warning when the attribute is applied to a defined
> > > symbol, but PR 92799 shows that it misses some cases on which it then
> > > leads to an ICE.
> > > 
> > > The ICE was introduced in GCC 4.5.  Prior to then, GCC accepted such
> > > invalid definitions and silently dropped the weakref attribute.
> > > 
> > > The attached patch avoids the ICE while again dropping the invalid
> > > attribute from the definition, except with the (now) usual warning.
> > > 
> > > Tested on x86_64-linux.
> > > 
> > > I also looked for code bases that make use of attribute weakref to
> > > rebuild them as another test but couldn't find any.  (There are
> > > a couple of instances in the Linux kernel but they look #ifdef'd
> > > out).  Does anyone know of any that do use it that I could try to
> > > build on Linux?
> > So you added this check
> > 
> > ... || DECL_INITIAL (decl) != error_mark_node
> > 
> > Do you need to check that DECL_INITIAL is not NULL?  IIUC DECL_INITIAL in
> > this
> > context is a tri-state.
> > 
> > NULL -- DECL is not a function definition
> > error_mark_node -- it was a function definition, but the body was free'd
> > everything else -- the function definition
> 
> I've only seen two values come up for a function declared weakref in
> the test suite: error_mark_node and something with the TREE_CODE of
> BLOCK (the block where the weakref function is used when it's also
> explicitly defined in the code, and when the attribute is subsequently
> diagnosed by the warning).
So when it's a BLOCK it's giving you the outermost block scope for the function
which we usually use to generate debug info.

The key point is that we use ERROR_MARK_NODE because a non-NULL DECL_INITIAL
denotes an actual function definition, so we can't set it to NULL blindly.  See
cgraph_node::expand, cgraph_node:release_body, rest_of_handle_final and perhaps
other places.  Another example would be setting up the ifunc resolver.  It's a
real function so DECL_INITIAL must be non-NULL, but we don't really have a block
structure we can point to, so instead we set it to error_mark_node
(make_dispatcher_decl).

I wonder if the earlier node->definition check ultimately prevents DECL_INITIAL
from being NULL at this point.  According to cgraph.h that field is true when 
the
symbol corresponds to a definition in the current unit.  That would seem to
indicate yes.

So I think we can go forward with your patch as-is.

jeff


Reply via email to