https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92123

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rguenth at gcc dot gnu.org

--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Yeah, I believe we don't need TREE_STATIC.  For DECL_CONTEXT, isn't the context
set already by pushdecl that gfc_create_var calls?
The reason why the *... = 42; store is removed is I believe invalid fn spec:
  gfor_fndecl_cfi_to_gfc = gfc_build_library_function_decl_with_spec (
        get_identifier (PREFIX("cfi_desc_to_gfc_desc")), ".ww",
        void_type_node, 2, pvoid_type_node, ppvoid_type_node);

  gfor_fndecl_gfc_to_cfi = gfc_build_library_function_decl_with_spec (
        get_identifier (PREFIX("gfc_desc_to_cfi_desc")), ".wR",
        void_type_node, 2, ppvoid_type_node, pvoid_type_node);

The first one looks weird, reading libgfortran sources, it doesn't look like
the second argument is ever stored into by the function, so shouldn't it be
".wr" instead?  And the ".wR" seems to be the reason why the testcase is
miscompiled with the #c10 patch minus TREE_STATIC hunk.  R means that the
argument is not written into (correct), that it does not escape (I'd say
incorrect) and that it is only accessed directly, not indirectly.
With incremental:
--- gcc/fortran/trans-decl.c.jj 2019-11-11 21:04:05.217259240 +0100
+++ gcc/fortran/trans-decl.c    2019-11-25 12:54:31.577424800 +0100
@@ -3739,11 +3742,11 @@ gfc_build_builtin_function_decls (void)
        void_type_node, 2, pvoid_type_node, pvoid_type_node);

   gfor_fndecl_cfi_to_gfc = gfc_build_library_function_decl_with_spec (
-       get_identifier (PREFIX("cfi_desc_to_gfc_desc")), ".ww",
+       get_identifier (PREFIX("cfi_desc_to_gfc_desc")), ".wr",
        void_type_node, 2, pvoid_type_node, ppvoid_type_node);

   gfor_fndecl_gfc_to_cfi = gfc_build_library_function_decl_with_spec (
-       get_identifier (PREFIX("gfc_desc_to_cfi_desc")), ".wR",
+       get_identifier (PREFIX("gfc_desc_to_cfi_desc")), ".wr",
        void_type_node, 2, ppvoid_type_node, pvoid_type_node);

   gfor_fndecl_associated = gfc_build_library_function_decl_with_spec (
it seems to work.  That r in there pretends it reads also e.g.
*GFC_DESCRIPTOR_DATA (s) and thus keeps the *... = 42; store.  Though, in
reality, for both functions what the second argument points to (the data
pointed by the descriptor) escapes, it doesn't escape to some global memory,
but to the pointer in the structure pointed by the first argument, in the
second call e.g.
void
gfc_desc_to_cfi_desc (CFI_cdesc_t **d_ptr, const gfc_array_void *s)
{
  CFI_cdesc_t *d;
  if (*d_ptr == NULL)
    d = malloc (...);
  else
    d = *d_ptr;
  d->base_addr = s->base_addr;
  ...
  if (*d_ptr == NULL)
    *d_ptr = d;
}

Richard, is ".wr" ok for that, even when it is lying, or should it be
".w." ?  I think there is no letter for doesn't store anything to the memory
directly and doesn't escape the address directly, but does escape the content
and thus indirect addresses.

Reply via email to