get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2218154/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2218154,
    "url": "http://patchwork.ozlabs.org/api/patches/2218154/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260331134403.53904-1-morin-mikael@orange.fr/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api",
        "name": "GNU Compiler Collection",
        "link_name": "gcc",
        "list_id": "gcc-patches.gcc.gnu.org",
        "list_email": "gcc-patches@gcc.gnu.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260331134403.53904-1-morin-mikael@orange.fr>",
    "list_archive_url": null,
    "date": "2026-03-31T13:44:03",
    "name": "[pushed] fortran: Give up reference factoring in case of shared tree [PR124661]",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "22345841a0d5d15028be454fb8edeeb1a89d0ffe",
    "submitter": {
        "id": 69402,
        "url": "http://patchwork.ozlabs.org/api/people/69402/?format=api",
        "name": "Mikael Morin",
        "email": "morin-mikael@orange.fr"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260331134403.53904-1-morin-mikael@orange.fr/mbox/",
    "series": [
        {
            "id": 498201,
            "url": "http://patchwork.ozlabs.org/api/series/498201/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=498201",
            "date": "2026-03-31T13:44:03",
            "name": "[pushed] fortran: Give up reference factoring in case of shared tree [PR124661]",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/498201/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2218154/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2218154/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=orange.fr header.i=@orange.fr header.a=rsa-sha256\n header.s=t20230301 header.b=JnrrKhyr;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org;\n\tdkim=pass (2048-bit key,\n unprotected) header.d=orange.fr header.i=@orange.fr header.a=rsa-sha256\n header.s=t20230301 header.b=JnrrKhyr",
            "sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=orange.fr",
            "sourceware.org; spf=pass smtp.mailfrom=orange.fr",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=80.12.242.73"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4flTrG5fwzz1yCp\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 01 Apr 2026 00:44:46 +1100 (AEDT)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id ECF874B35882\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 31 Mar 2026 13:44:44 +0000 (GMT)",
            "from smtp.smtpout.orange.fr (smtp-73.smtpout.orange.fr\n [80.12.242.73])\n by sourceware.org (Postfix) with ESMTPS id BAF944B7A1E4;\n Tue, 31 Mar 2026 13:44:09 +0000 (GMT)",
            "from cyrano.home ([IPv6:2a01:cb08:8462:ff00:635d:298a:2b99:c0c0])\n by smtp.orange.fr with ESMTPSA\n id 7ZNywDXqjWGxq7ZO3w4wAX; Tue, 31 Mar 2026 15:44:08 +0200"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org ECF874B35882",
            "OpenDKIM Filter v2.11.0 sourceware.org BAF944B7A1E4"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org BAF944B7A1E4",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org BAF944B7A1E4",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1774964649; cv=none;\n b=k+kFiLnH11aCYPojHH+TUPHolxw52eidhDZAmj1APL4uaUKDadQ7n3i3QMTuhNkYkc7seZDP2lYiJ+UnGwF09rrClQ91B3GDPKsWwpYUFVqJJIg/cODxI86IeKLtxYBmCQC2hB1L0BjAFmJFKe6Z8c2ze9sjE6MT1HiT49scL+Q=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1774964649; c=relaxed/simple;\n bh=o5ZhztLNyX4iwdPhAjNVwvR2KtPDC4gmucKKIEeiezM=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=HviduJ8Pkn3quP1mJ2ngGGcvPXUbfg+BLOi9fwCcJCzf2a4kFZ0WswsCOhXK7++bb33AvUKv0j1HDNuM2m2O6sRy6tc/VYKMAzEbm0tLSubBU0+61BDpP2Z4EZS0D/E5kRoL2U+NlJ+f/FJEl9SZ5joAiwJSKMvsMy3bbpfaPRE=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=orange.fr;\n s=t20230301; t=1774964648;\n bh=33NC9gEFxWz6B+KpTZmK1tezOK54PnR7FVwi/lZvWRE=;\n h=From:To:Subject:Date:Message-ID:MIME-Version;\n b=JnrrKhyrnpdIqDch9mR5I3QGVbcuplK+asNN+K9UuijV4RMI2lVKuXya2s+60OWaM\n 0WqacKaduRnwnLuLZGMpX8y0bU2tpavzgc530lwW582BEK/Xm6vi/OpXQWO94yJDLy\n c1WfQKdcL7sl4qbvzuQMNY1Jz5nSWPudJUSnsTjor/kbZwR9vX58fHQRwbhsKlmBBD\n kBo09FJ08aihxl1bEpYSbhiuBZG/wiKWxC1HSZPceBiYFTN3MyTP6g/HDHveVRoEiN\n c57s2/Nr+27Vo1Uq4kWygrOsrLqCtZ0KXSBAJy/7mk5YTu+F8ptwWtcMAWDOptZ5B/\n X3njHV6yywdqw==",
        "X-ME-Helo": "cyrano.home",
        "X-ME-Auth": "bW9yaW4tbWlrYWVsQG9yYW5nZS5mcg==",
        "X-ME-Date": "Tue, 31 Mar 2026 15:44:08 +0200",
        "X-ME-IP": "2a01:cb08:8462:ff00:635d:298a:2b99:c0c0",
        "From": "Mikael Morin <morin-mikael@orange.fr>",
        "To": "gcc-patches@gcc.gnu.org,\n\tfortran@gcc.gnu.org",
        "Cc": "Christopher Albert <albert@tugraz.at>",
        "Subject": "[pushed] fortran: Give up reference factoring in case of shared tree\n [PR124661]",
        "Date": "Tue, 31 Mar 2026 15:44:03 +0200",
        "Message-ID": "<20260331134403.53904-1-morin-mikael@orange.fr>",
        "X-Mailer": "git-send-email 2.53.0",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "gcc-patches@gcc.gnu.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>",
        "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>",
        "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>",
        "List-Post": "<mailto:gcc-patches@gcc.gnu.org>",
        "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>",
        "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "From: Mikael Morin <mikael@gcc.gnu.org>\n\nWhen we are about to create a variable to factor a subreference of an\narray descriptor, check whether that subreference is shared with some of\nthe preliminary code and abort the factoring in that case.\n\nIn the example from the PR, the preliminary code contained bounds\nchecking code and the replacement of the subreferences by fresh\nvariables was causing those variables to be used before they were\ndefined in that bounds checking code.\n\n\tPR fortran/121185\n\tPR fortran/124661\n\ngcc/fortran/ChangeLog:\n\n\t* trans-array.cc (maybe_save_ref): New wrapper function around\n\tsave ref.\n\t(set_factored_descriptor_value): Use the new wrapper function.\n\tAdd argument PRELIMINARY_CODE.\n\t(gfc_conv_ss_descriptor): Update caller.\n\ngcc/ChangeLog:\n\n\t* tree-inline.cc (debug_find_tree, debug_find_tree_1): Move\n\tand rename functions...\n\t* tree.cc (find_tree, find_tree_1): ... here.\n\t* tree-inline.h (debug_find_tree): Move renamed declaration...\n\t* tree.h (find_tree): ... here.\n\ngcc/testsuite/ChangeLog:\n\n\t* gfortran.dg/bounds_check_28.f90: New test.\n\nCo-authored-by: Christopher Albert <albert@tugraz.at>\n---\n gcc/fortran/trans-array.cc                    | 37 ++++++++--\n gcc/testsuite/gfortran.dg/bounds_check_28.f90 | 70 +++++++++++++++++++\n gcc/tree-inline.cc                            | 18 -----\n gcc/tree-inline.h                             |  1 -\n gcc/tree.cc                                   | 20 ++++++\n gcc/tree.h                                    |  3 +\n 6 files changed, 123 insertions(+), 26 deletions(-)\n create mode 100644 gcc/testsuite/gfortran.dg/bounds_check_28.f90",
    "diff": "diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc\nindex a2da4fe7c7d..4ab1d04440d 100644\n--- a/gcc/fortran/trans-array.cc\n+++ b/gcc/fortran/trans-array.cc\n@@ -3520,20 +3520,37 @@ save_ref (tree &code, tree &ref, vec<tree> &replacement_roots)\n }\n \n \n+/* If REF isn't shared with code in PREVIOUS_CODE, replace it with a fresh\n+   variable in all of REPLACEMENT_ROOTS, appending extra code to CODE.  */\n+\n+static void\n+maybe_save_ref (tree &code, tree &ref, vec<tree> &replacement_roots,\n+\t\tstmtblock_t *previous_code)\n+{\n+  if (find_tree (previous_code->head, ref))\n+    return;\n+\n+  save_ref (code, ref, replacement_roots);\n+}\n+\n+\n /* Save the descriptor reference VALUE to storage pointed by DESC_PTR.  Before\n-   that, try to factor subexpressions of VALUE to variables, adding extra code\n-   to BLOCK.\n+   that, try to create fresh variables to factor subexpressions of VALUE, if\n+   those subexpressions aren't shared with code in PRELIMINARY_CODE.  Add any\n+   necessary additional code (initialization of variables typically) to BLOCK.\n \n    The candidate references to factoring are dereferenced pointers because they\n    are cheap to copy and array descriptors because they are often the base of\n    multiple subreferences.  */\n \n static void\n-set_factored_descriptor_value (tree *desc_ptr, tree value, stmtblock_t *block)\n+set_factored_descriptor_value (tree *desc_ptr, tree value, stmtblock_t *block,\n+\t\t\t       stmtblock_t *preliminary_code)\n {\n   /* As the reference is processed from outer to inner, variable definitions\n      will be generated in reversed order, so can't be put directly in BLOCK.\n-     We use TMP_BLOCK instead.  */\n+     We use temporary blocks instead, which we save in ACCUMULATED_CODE, and\n+     only append to BLOCK at the end.  */\n   tree accumulated_code = NULL_TREE;\n \n   /* The current candidate to factoring.  */\n@@ -3572,7 +3589,8 @@ set_factored_descriptor_value (tree *desc_ptr, tree value, stmtblock_t *block)\n \t\t     previous reference to save wasn't the current one, do save\n \t\t     it now.  Otherwise drop it as we prefer saving the\n \t\t     pointer.  */\n-\t\t  save_ref (accumulated_code, saveable_ref, replacement_roots);\n+\t\t  maybe_save_ref (accumulated_code, saveable_ref,\n+\t\t\t\t  replacement_roots, preliminary_code);\n \t\t}\n \n \t      /* Don't evaluate the pointer to a variable yet; do it only if the\n@@ -3602,7 +3620,8 @@ set_factored_descriptor_value (tree *desc_ptr, tree value, stmtblock_t *block)\n \n \t  if (saveable_ref != NULL_TREE)\n \t    /* We have seen a reference worth saving.  Do it now.  */\n-\t    save_ref (accumulated_code, saveable_ref, replacement_roots);\n+\t    maybe_save_ref (accumulated_code, saveable_ref, replacement_roots,\n+\t\t\t    preliminary_code);\n \n \t  if (TREE_CODE (data_ref) != ARRAY_REF)\n \t    break;\n@@ -3635,8 +3654,12 @@ gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)\n   gfc_init_se (&se, NULL);\n   se.descriptor_only = 1;\n   gfc_conv_expr_lhs (&se, ss_info->expr);\n+  stmtblock_t tmp_block;\n+  gfc_init_block (&tmp_block);\n+  set_factored_descriptor_value (&info->descriptor, se.expr, &tmp_block,\n+\t\t\t\t &se.pre);\n   gfc_add_block_to_block (block, &se.pre);\n-  set_factored_descriptor_value (&info->descriptor, se.expr, block);\n+  gfc_add_block_to_block (block, &tmp_block);\n   ss_info->string_length = se.string_length;\n   ss_info->class_container = se.class_container;\n \ndiff --git a/gcc/testsuite/gfortran.dg/bounds_check_28.f90 b/gcc/testsuite/gfortran.dg/bounds_check_28.f90\nnew file mode 100644\nindex 00000000000..0947e308e7a\n--- /dev/null\n+++ b/gcc/testsuite/gfortran.dg/bounds_check_28.f90\n@@ -0,0 +1,70 @@\n+! { dg-do run }\n+! { dg-options \"-fcheck=bounds\" }\n+!\n+! PR fortran/124661\n+! Check that the temporary variables used to prevent redundant data\n+! references aren't used uninitialized in the bounds checking code.\n+!\n+! Original testcase from Jakub Benda <albandil at atlas dot cz>.\n+! Extended and adapted to the testsuite by Christopher Albert <albert at tugraz dot at>.\n+\n+module m\n+  implicit none\n+\n+  type point_t\n+    real :: coords(1:3)\n+  end type point_t\n+\n+  type intermediary_t\n+    type(point_t), allocatable :: ac(:)\n+  end type intermediary_t\n+\n+  type point_cloud_t\n+    type(point_t), allocatable :: points(:)\n+  contains\n+    procedure :: init_point_cloud\n+  end type point_cloud_t\n+\n+  type nested_point_cloud_t\n+    type(intermediary_t), allocatable :: points(:)\n+  contains\n+    procedure :: init_nested_point_cloud\n+  end type nested_point_cloud_t\n+\n+contains\n+\n+  subroutine init_point_cloud (c)\n+    class(point_cloud_t) :: c\n+    real :: expected(3)\n+\n+    expected = [1.0, 2.0, 3.0]\n+    allocate (c%points(1))\n+    c%points(1)%coords = expected\n+\n+    if (c%points(1)%coords(3) /= expected(3)) stop 1\n+    if (any (c%points(1)%coords /= expected)) stop 2\n+  end subroutine init_point_cloud\n+\n+  subroutine init_nested_point_cloud (c)\n+    class(nested_point_cloud_t) :: c\n+    real :: expected(3)\n+\n+    expected = [4.0, 5.0, 6.0]\n+    allocate (c%points(1))\n+    allocate (c%points(1)%ac(1))\n+    c%points(1)%ac(1)%coords = expected\n+\n+    if (c%points(1)%ac(1)%coords(3) /= expected(3)) stop 3\n+    if (any (c%points(1)%ac(1)%coords /= expected)) stop 4\n+  end subroutine init_nested_point_cloud\n+end module m\n+\n+program p\n+  use m, only: nested_point_cloud_t, point_cloud_t\n+  implicit none\n+  type(point_cloud_t) :: c\n+  type(nested_point_cloud_t) :: nested\n+\n+  call c%init_point_cloud\n+  call nested%init_nested_point_cloud\n+end program p\ndiff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc\nindex 087fcc8a8b8..df5597ef30d 100644\n--- a/gcc/tree-inline.cc\n+++ b/gcc/tree-inline.cc\n@@ -6057,24 +6057,6 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq)\n }\n \n \n-/* Allow someone to determine if SEARCH is a child of TOP from gdb.  */\n-\n-static tree\n-debug_find_tree_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)\n-{\n-  if (*tp == data)\n-    return (tree) data;\n-  else\n-    return NULL;\n-}\n-\n-DEBUG_FUNCTION bool\n-debug_find_tree (tree top, tree search)\n-{\n-  return walk_tree_without_duplicates (&top, debug_find_tree_1, search) != 0;\n-}\n-\n-\n /* Declare the variables created by the inliner.  Add all the variables in\n    VARS to BIND_EXPR.  */\n \ndiff --git a/gcc/tree-inline.h b/gcc/tree-inline.h\nindex 4642c87f89b..aeedab0c26f 100644\n--- a/gcc/tree-inline.h\n+++ b/gcc/tree-inline.h\n@@ -242,7 +242,6 @@ bool tree_versionable_function_p (tree);\n extern tree remap_decl (tree decl, copy_body_data *id);\n extern tree remap_type (tree type, copy_body_data *id);\n extern gimple_seq copy_gimple_seq_and_replace_locals (gimple_seq seq);\n-extern bool debug_find_tree (tree, tree);\n extern tree copy_fn (tree, tree&, tree&);\n extern const char *copy_forbidden (struct function *fun);\n extern tree copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy);\ndiff --git a/gcc/tree.cc b/gcc/tree.cc\nindex d0e745e8d28..2868cb0867d 100644\n--- a/gcc/tree.cc\n+++ b/gcc/tree.cc\n@@ -15298,6 +15298,26 @@ verify_type_context (location_t loc, type_context_kind context,\n \t  || targetm.verify_type_context (loc, context, type, silent_p));\n }\n \n+/* Callback of walk_tree telling whether the current tree pointed by TP is the\n+   one provided as DATA.  */\n+\n+static tree\n+find_tree_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)\n+{\n+  if (*tp == data)\n+    return (tree) data;\n+  else\n+    return NULL;\n+}\n+\n+/* Return whether SEARCH is a subtree of TOP.  */\n+\n+bool\n+find_tree (tree top, tree search)\n+{\n+  return walk_tree_without_duplicates (&top, find_tree_1, search) != 0;\n+}\n+\n /* Return true if NEW_ASM and DELETE_ASM name a valid pair of new and\n    delete operators.  Return false if they may or may not name such\n    a pair and, when nonnull, set *PCERTAIN to true if they certainly\ndiff --git a/gcc/tree.h b/gcc/tree.h\nindex 19bc67718d1..f8b2d718b7e 100644\n--- a/gcc/tree.h\n+++ b/gcc/tree.h\n@@ -6001,6 +6001,9 @@ extern int get_range_pos_neg (tree, gimple * = NULL);\n /* Return true for a valid pair of new and delete operators.  */\n extern bool valid_new_delete_pair_p (tree, tree, bool * = NULL);\n \n+/* Return whether the second argument is a subtree of the first one.  */\n+extern bool find_tree (tree, tree);\n+\n /* Return simplified tree code of type that is used for canonical type\n    merging.  */\n inline enum tree_code\n",
    "prefixes": [
        "pushed"
    ]
}