get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2216544,
    "url": "http://patchwork.ozlabs.org/api/patches/2216544/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260326172849.71000-1-iain@sandoe.co.uk/",
    "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": "<20260326172849.71000-1-iain@sandoe.co.uk>",
    "list_archive_url": null,
    "date": "2026-03-26T17:28:38",
    "name": "c++, contracts: No implicit capture in lambda contract assertions [PR124648].",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "06e202ae9ec374ceb7f410050ffe57d243db812f",
    "submitter": {
        "id": 80672,
        "url": "http://patchwork.ozlabs.org/api/people/80672/?format=api",
        "name": "Iain Sandoe",
        "email": "iains.gcc@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260326172849.71000-1-iain@sandoe.co.uk/mbox/",
    "series": [
        {
            "id": 497631,
            "url": "http://patchwork.ozlabs.org/api/series/497631/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=497631",
            "date": "2026-03-26T17:28:38",
            "name": "c++, contracts: No implicit capture in lambda contract assertions [PR124648].",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/497631/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2216544/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2216544/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=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=ZjBN0363;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.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=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=ZjBN0363",
            "sourceware.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com",
            "sourceware.org; spf=pass smtp.mailfrom=gmail.com",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=209.85.221.54"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org [38.145.34.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 4fhW3l4HyBz1y1G\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 27 Mar 2026 04:29:23 +1100 (AEDT)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id B12D84BA23F9\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 26 Mar 2026 17:29:21 +0000 (GMT)",
            "from mail-wr1-f54.google.com (mail-wr1-f54.google.com\n [209.85.221.54])\n by sourceware.org (Postfix) with ESMTPS id 1746C4B9DB7D\n for <gcc-patches@gcc.gnu.org>; Thu, 26 Mar 2026 17:28:52 +0000 (GMT)",
            "by mail-wr1-f54.google.com with SMTP id\n ffacd0b85a97d-43b9144790dso699209f8f.1\n for <gcc-patches@gcc.gnu.org>; Thu, 26 Mar 2026 10:28:52 -0700 (PDT)",
            "from localhost.localdomain (host81-138-1-83.in-addr.btopenworld.com.\n [81.138.1.83]) by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-43b91943184sm8555181f8f.14.2026.03.26.10.28.50\n (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256);\n Thu, 26 Mar 2026 10:28:50 -0700 (PDT)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org B12D84BA23F9",
            "OpenDKIM Filter v2.11.0 sourceware.org 1746C4B9DB7D"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 1746C4B9DB7D",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 1746C4B9DB7D",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1774546132; cv=none;\n b=kT08RwLXI5VIPhMu1dPzZjJW835SYfSXMKrXWpPHxqE+VIkwlbG3wJsK9bl+Qg8pSYaGUMw6luFGZaNc1xlhbBxR78sYhShJZLhdMGikEciR2wcIUq+gLWUrmVsVQ3OqOgL3Jgwbp5gkn6gpmB3kJt9QOCt739VwCsPQMRISVhU=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1774546132; c=relaxed/simple;\n bh=5IYeGLaNw7rbbWqBKDSnIRHTOUrm4SW9at0Wkuzxono=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=lOtGaBs9hxfDAQP9dEqWfQIV33+RkNH8VSSgb+ZlYwjsa09Xmo7/T6SVF+eCEncR3YKabLhdW6rR1Enrg2hWzdud01MY/9eKBMWrbto5i/lF3BoU/Mf4Ss4whMTqWz08NE2fd5ACcahwOP+Jidklb8eq0gr/xI0057ityNAQ8hA=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1774546131; x=1775150931; darn=gcc.gnu.org;\n h=content-transfer-encoding:mime-version:reply-to:message-id:date\n :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to;\n bh=s0jmr66QCNWXBTCOjraGy3BPY8B+bILleSZR27fxMh4=;\n b=ZjBN0363uOvcdITgDtQSvh0nsBKCfQnW7Xa44hbXWsK+n8T2mbvHcbQjyvrQk4IB5d\n 8W6GCz+/ZposY2SoQAr4/QV39uSH+iNPxt42W/bVOp7/vpf5rL0gf/G6bFc44NwNyyck\n 3flN5Ie941OZLOv976ppTlCPE2lRjcu21pFtgkdX3kvI03OMFIOzymYl9xdf4M4aWnUk\n /KIyLpGrV7GxxxEERaLcwLtNuAWUvurBZqjLgMjlFnrOgKjxDTTFLZbVmYY1FtK/gU1+\n deK7JpkWozmH+2aiphrK+8+YrZ70Yquw5AZg8pELwXRLseQGBKsh59s7W3ODyEmhQyaj\n 5T+A==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1774546131; x=1775150931;\n h=content-transfer-encoding:mime-version:reply-to:message-id:date\n :subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject\n :date:message-id:reply-to;\n bh=s0jmr66QCNWXBTCOjraGy3BPY8B+bILleSZR27fxMh4=;\n b=BQR2Xyn9MhMulrrulweyugIY540VwIj592biSV6YIRSFXmCAFAMhIORFpEqXBf+6y4\n R7+CvxuIzV4OJdkBDmCmN3tO066HjbqEowO0ut/KgiliCNuS+ivM+V02VYeBUBkkPc4Y\n yjFsC2c7Y2YBwWEhcFDIOeI7kWw3HPkacS3SOKWAeOLRfORv9/rDta9SCfL+8dAp6tKs\n C0Uc1R+tM0Tkw5mvuV5HQM/MMVA08qEbKpt4xh9p9hjdF3FusPxEWQ5M/UIhONMdAen2\n 5B/D3QWIaOgbJ6jOj/O0m02HNKic9nP3d4gIOSpKLz7fJQsHG8Zdue3bke7oZcuIbE6T\n gxoA==",
        "X-Gm-Message-State": "AOJu0YyW2f9FSm3+07haJHktr5+v/UmB5oi4ApEiJCGopq0Rk40sn+zj\n 6+R5F8PqbJpRQWti0pvrrf2M4iR4HX5p20ypxJK9AMGlHmOvjx2APcGx0PlQaQ==",
        "X-Gm-Gg": "ATEYQzxVJ9m5jEMYtXj8U+ZH+fpDejZoYr5sB3cUIIPRlQQ4gNHcfk9ErFZ4QHI+gDp\n AH3yekfUeDnREOV3MzNbS1JHgMwaZU8wN3CDKYT91re+G6shiLpl2gS2sJ0PE+X7mCdWOYHA/ZG\n o8mxotK7OcuNIOSljwQ8jf4iJIWfkD2QxNQ6kdhE1i+ofNiX3A5AjqQnWv23py6QFWRmu6mZNpW\n ApnlRlKDbh+egRRyxTKOhLMXvRRj01+m98FLYzxpN4A1T4u8XO4ZgLvqpWIfGSwKp0+jUFPufJ/\n BAYvPsS8pLM0RenMtIwS5ce973TgSX511jIKAlQX27W8A7IeMo48hRxM1v35P6VMYeBUMB1Tfjx\n ZoCtluuAPB2myZKQAGmXyZ+CeWmrWnIG/6SDsJNDHCgR4cFV0YwuCO9w5peQYg+VwYW2iIPH3Kb\n /E2Cz2I63BvzjjBbYwxcmU7Ge4J1f5Vr6LGgkqjovd/HLh9PXRgWjyXQqDhNlDZ6C0sE5lUSrA7\n bdZ3y/9HGFeZsNpQCGmuA==",
        "X-Received": "by 2002:a5d:64e4:0:b0:439:b539:787 with SMTP id\n ffacd0b85a97d-43b88a44771mr13128282f8f.53.1774546130563;\n Thu, 26 Mar 2026 10:28:50 -0700 (PDT)",
        "From": "Iain Sandoe <iains.gcc@gmail.com>",
        "X-Google-Original-From": "Iain Sandoe <iain@sandoe.co.uk>",
        "To": "gcc-patches@gcc.gnu.org",
        "Cc": "jason@redhat.com",
        "Subject": "[PATCH] c++,\n contracts: No implicit capture in lambda contract assertions\n [PR124648].",
        "Date": "Thu, 26 Mar 2026 17:28:38 +0000",
        "Message-ID": "<20260326172849.71000-1-iain@sandoe.co.uk>",
        "X-Mailer": "git-send-email 2.50.1",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "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>",
        "Reply-To": "iain@sandoe.co.uk",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "This does also lead to an ICE on invalid, per the referenced PR.\n\nTested on x86_64 darwin, x86_64, powerpc64le Linux,\nOK for trunk?\nthanks\nIain\n\n--- 8< ---\n\nWe were currently accepting invalid code by allowing contract assertions\nto trigger implicit lambda captures contrary to:\n[expr.prim.lambda.closure] / p10.\n\nThe solution here is to mark captures that occur within contract\nassertion scopes and then clear that mark if we then see a normal\ncapture for the same entity - we must defer the error handling since\nthe following is valid:\n\n  auto f5 = [=] {\n    contract_assert (i > 0); // OK, i is referenced elsewhere.\n    return i;\n  };\n\n\tPR c++/124648\n\ngcc/cp/ChangeLog:\n\n\t* cp-tree.h (DECL_CONTRACT_CAPTURE_P): New.\n\t* parser.cc (cp_parser_lambda_body): Scan the captures for\n\tones were only added in contract assertion scopes.  Issue\n\terrors for those found.\n\t* semantics.cc (process_outer_var_ref): Mark implicit\n\tcaptures that occur in contract assertion scopes.  Clear\n\tthe mark if the entity is subsequently captured 'normally'.\n\ngcc/testsuite/ChangeLog:\n\n\t* g++.dg/contracts/cpp26/expr.prim.lambda.closure.p10.C: New test.\n\nSigned-off-by: Iain Sandoe <iain@sandoe.co.uk>\n---\n gcc/cp/cp-tree.h                              |  3 ++\n gcc/cp/parser.cc                              | 20 +++++++\n gcc/cp/semantics.cc                           | 27 ++++++++--\n .../cpp26/expr.prim.lambda.closure.p10.C      | 53 +++++++++++++++++++\n 4 files changed, 100 insertions(+), 3 deletions(-)\n create mode 100644 gcc/testsuite/g++.dg/contracts/cpp26/expr.prim.lambda.closure.p10.C",
    "diff": "diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h\nindex ea3cb049785..7beaae6bbfd 100644\n--- a/gcc/cp/cp-tree.h\n+++ b/gcc/cp/cp-tree.h\n@@ -5367,6 +5367,9 @@ get_vec_init_expr (tree t)\n #define DECL_NORMAL_CAPTURE_P(NODE) \\\n   DECL_LANG_FLAG_7 (FIELD_DECL_CHECK (NODE))\n \n+#define DECL_CONTRACT_CAPTURE_P(NODE) \\\n+  DECL_LANG_FLAG_8 (FIELD_DECL_CHECK (NODE))\n+\n /* Nonzero if TYPE is an anonymous union or struct type.  We have to use a\n    flag for this because \"A union for which objects or pointers are\n    declared is not an anonymous union\" [class.union].  */\ndiff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc\nindex 8d88dc9c312..e5157cd7386 100644\n--- a/gcc/cp/parser.cc\n+++ b/gcc/cp/parser.cc\n@@ -13740,6 +13740,26 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)\n        finish_function (which will try to emit the contracts).  */\n     cp_parser_late_contracts (parser, fco);\n \n+    /* Check that we have not caused captures that only relate to contracts.\n+       [expr.prim.lambda.closure] / P10.  */\n+    if (flag_contracts)\n+      {\n+\ttree le = LAMBDA_EXPR_CAPTURE_LIST (current_lambda_expr ());\n+\tfor (; le; le = TREE_CHAIN (le))\n+\t  {\n+\t    tree cap_fld = TREE_PURPOSE (le);\n+\t    if (TREE_CODE (cap_fld) == FIELD_DECL\n+\t\t&& DECL_CONTRACT_CAPTURE_P (cap_fld))\n+\t      {\n+\t\tauto_diagnostic_group d;\n+\t\ttree expr = TREE_VALUE (le);\n+\t\tlocation_t loc = DECL_SOURCE_LOCATION (cap_fld);\n+\t\terror_at (loc, \"%qE is not implicitly captured by a contract\"\n+\t\t\t  \" assertion\", expr);\n+\t\tinform (DECL_SOURCE_LOCATION (expr), \"%q#E declared here\", expr);\n+\t      }\n+\t  }\n+      }\n     finish_lambda_function (body);\n   }\n \ndiff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc\nindex ac08b598f3d..992ae29a4f4 100644\n--- a/gcc/cp/semantics.cc\n+++ b/gcc/cp/semantics.cc\n@@ -4619,6 +4619,17 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)\n \n       if (d && d != decl && is_capture_proxy (d))\n \t{\n+\t  if (flag_contracts && !processing_contract_condition)\n+\t    {\n+\t      /* We might have created a capture for a contract_assert ref. to\n+\t\t some var, if that is now captured 'normally' then this is OK.\n+\t\t Otherwise we leave the capture marked as incorrect.  */\n+\t      gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (d));\n+\t      tree proxy = DECL_VALUE_EXPR (d);\n+\t      gcc_checking_assert (TREE_CODE (proxy) == COMPONENT_REF\n+\t\t\t\t&& TREE_CODE (TREE_OPERAND (proxy, 1)) == FIELD_DECL);\n+              DECL_CONTRACT_CAPTURE_P (TREE_OPERAND (proxy, 1)) = false;\n+\t    }\n \t  if (DECL_CONTEXT (d) == containing_function)\n \t    /* We already have an inner proxy.  */\n \t    return d;\n@@ -4667,10 +4678,20 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)\n       return error_mark_node;\n     }\n   /* Do lambda capture when processing the id-expression, not when\n-     odr-using a variable.  */\n+     odr-using a variable, but uses in a contract must not cause a capture.  */\n   if (!odr_use && context == containing_function)\n-    decl = add_default_capture (lambda_stack,\n-\t\t\t\t/*id=*/DECL_NAME (decl), initializer);\n+    {\n+      decl = add_default_capture (lambda_stack,\n+\t\t\t\t  /*id=*/DECL_NAME (decl), initializer);\n+      if (flag_contracts && processing_contract_condition)\n+\t{\n+\t  gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (decl));\n+\t  tree proxy = DECL_VALUE_EXPR (decl);\n+\t  gcc_checking_assert (TREE_CODE (proxy) == COMPONENT_REF\n+\t\t\t\t&& TREE_CODE (TREE_OPERAND (proxy, 1)) == FIELD_DECL);\n+          DECL_CONTRACT_CAPTURE_P (TREE_OPERAND (proxy, 1)) = true;\n+        }\n+    }\n   /* Only an odr-use of an outer automatic variable causes an\n      error, and a constant variable can decay to a prvalue\n      constant without odr-use.  So don't complain yet.  */\ndiff --git a/gcc/testsuite/g++.dg/contracts/cpp26/expr.prim.lambda.closure.p10.C b/gcc/testsuite/g++.dg/contracts/cpp26/expr.prim.lambda.closure.p10.C\nnew file mode 100644\nindex 00000000000..5a165c48166\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/contracts/cpp26/expr.prim.lambda.closure.p10.C\n@@ -0,0 +1,53 @@\n+// N5008 :\n+// [expr.prim.lambda.closure]/p10\n+// If all potential references to a local entity implicitly captured by a\n+// lambda-expression L occur within the function contract assertions of the\n+// call operator or operator template of L or within assertion-statements\n+// within the body of L, the program is ill-formed.\n+// [Note 4: Adding a contract assertion to an existing C++ program cannot\n+//  cause additional captures. — end note]\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-fcontracts -fsyntax-only\" }\n+\n+auto gl0 = [] (int x) \n+  pre (x > 10) { return x; }; // OK\n+\n+static int i = 0;\n+\n+void\n+foo ()\n+{\n+  auto f1 = [=]\n+    pre (i > 0) {};  // OK, no local entities are captured.\n+\n+  int i = 1;\n+\n+  auto f2 = [=]\n+    pre (i > 0) {};  // { dg-error {'i' is not implicitly captured by a contract assertion} }\n+\n+  auto f3 = [i]\n+    pre (i > 0) {};  // OK, i is captured explicitly.\n+\n+  auto f4 = [=] {\n+    contract_assert (i > 0); // { dg-error {'i' is not implicitly captured by a contract assertion} }\n+  };\n+\n+  auto f5 = [=] {\n+    contract_assert (i > 0); // OK, i is referenced elsewhere.\n+    return i;\n+  };\n+\n+  auto f6 = [=] pre (                // #1\n+    []{\n+      bool x = true;\n+      return [=]{ return x; }();    // OK, #1 captures nothing.\n+    }()) {};\n+\n+// TODO: lambda captures in function contract specifiers are not yet\n+// fully functional.\n+#if 0\n+  bool y = true;\n+  auto f7 = [=]\n+    pre([=]{ return y; }()); // error: outer capture of y is invalid.\n+#endif\n+}\n",
    "prefixes": []
}