On 1/11/19 1:10 PM, Martin Sebor wrote:
> The attached patch extends the detection of references to static
> variables in inline functions to the function signatures, including
> their return type. Since the declaration of a function need not be
> yet available at the time the static is referenced (e.g., when it's
> referenced in the functions return type), the patch introduces
> the concept of "tentative records" of such references and either
> completes the records when the full declaration of the function,
> including its definition, is known to be inline, or removes it
> when it isn't.
>
> Martin
>
> gcc-88718.diff
>
> PR c/88718 - Strange inconsistency between old style and new style
> definitions of inline functions.
>
> gcc/c/ChangeLog:
>
> PR c/88718
> * c-decl.c (reset_inline_statics): New function.
> (record_inline_static): Optimize.
> (check_inline_statics): Handle tentative records for inline
> declarations without definitions.
> Print static declaration location.
> (push_file_scope): Clear records of references to statics.
> (finish_decl): Add tentative records of references to statics.
> (finish_function): Same.
> * c-typeck.c (build_external_ref): Handle all references to statics.
>
> gcc/testsuite/ChangeLog:
>
> PR c/88718
> * gcc.dg/inline-40.c: New test.
> * gcc.dg/inline-41.c: New test.
>
> Index: gcc/c/c-decl.c
> ===================================================================
> --- gcc/c/c-decl.c (revision 267616)
> +++ gcc/c/c-decl.c (working copy)
> @@ -826,14 +826,47 @@ c_finish_incomplete_decl (tree decl)
> }
> }
>
> -/* Record that inline function FUNC contains a reference (location
> - LOC) to static DECL (file-scope or function-local according to
> - TYPE). */
> +/* Free records of references to static variables gathered so far. */
>
> +static void
> +reset_inline_statics (void)
> +{
> + if (!c_inline_statics)
> + return;
> +
> + for (c_inline_static *csi = c_inline_statics, *next = csi->next;
> + csi; csi = next)
> + ggc_free (csi);
> +
> + c_inline_statics = NULL;
> +}
> +
> +/* Record that inline function FUNC either does contain or may contain
> + a reference (location LOC) to static DECL (file-scope or function-local
> + according to TYPE). For a null FUNC, a tentative record is created that
> + reflects a reference in the function signature and that is either updated
> + or removed when the function declaration is complete. */
> +
> void
> record_inline_static (location_t loc, tree func, tree decl,
> enum c_inline_static_type type)
> {
> + gcc_assert (decl);
> +
> + if (c_inline_statics)
> + {
> + /* Avoid adding another tentative record for this DECL if one
> + already exists. */
> + for (c_inline_static *csi = c_inline_statics; csi; csi = csi->next)
> + {
> + if (c_inline_statics->function)
> + break;
> +
> + if (decl == c_inline_statics->static_decl)
> + return;
> + }
> + }
> +
I'm going to assume this isn't called enough for the linear search to
matter from a compile-time standpoint.
OK for the trunk.
Jeff