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).

The weakref attribute provides a definition for a declaration that
is not a definition.  DECL_INITIAL is set to error_mark_node in
handle_alias_ifunc_attribute called (indirectly) from
handle_weakref_attribute.  So case 1 never comes up and cases 2 and
3 above are an error.  Once defined by the means of the attribute,
the function can be redeclared but its DECL_INITIAL is still
error_mark_node.

For DECL_INITIAL (decl) weakref variables DECL_INITIAL is set to null
(in this case GCC issues a warning and ignores the attribute).  I don't
know why functions have this special treatment and there's no comment
to explain.

Anyway, I don't have a problem adding the check but (as always) I'd
like to be able to test it.  Let me know if you know how, or what
you want me to do.

Martin

Reply via email to