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.