get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2233046,
    "url": "http://patchwork.ozlabs.org/api/1.2/patches/2233046/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260505151030.1749548-9-waffl3x@baylibre.com/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/1.2/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": "<20260505151030.1749548-9-waffl3x@baylibre.com>",
    "list_archive_url": null,
    "date": "2026-05-05T15:02:01",
    "name": "[08/12] OpenMP/C++: Add static analysis of allocate directive allocator clause",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "19d2fcc2fef275d2ae4849bad48f243d1a9b7599",
    "submitter": {
        "id": 90070,
        "url": "http://patchwork.ozlabs.org/api/1.2/people/90070/?format=api",
        "name": "Waffl3x",
        "email": "waffl3x@baylibre.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260505151030.1749548-9-waffl3x@baylibre.com/mbox/",
    "series": [
        {
            "id": 502853,
            "url": "http://patchwork.ozlabs.org/api/1.2/series/502853/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=502853",
            "date": "2026-05-05T15:01:54",
            "name": "OpenMP/C++: 'allocate' directive",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/502853/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2233046/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2233046/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=baylibre-com.20251104.gappssmtp.com\n header.i=@baylibre-com.20251104.gappssmtp.com header.a=rsa-sha256\n header.s=20251104 header.b=pgrdbNp/;\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=baylibre-com.20251104.gappssmtp.com\n header.i=@baylibre-com.20251104.gappssmtp.com header.a=rsa-sha256\n header.s=20251104 header.b=pgrdbNp/",
            "sourceware.org;\n dmarc=none (p=none dis=none) header.from=baylibre.com",
            "sourceware.org; spf=pass smtp.mailfrom=baylibre.com",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=2607:f8b0:4864:20::429"
        ],
        "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 4g92BK2Z2Dz1yJ0\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 06 May 2026 01:15:05 +1000 (AEST)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 5E02A4B9DB40\n\tfor <incoming@patchwork.ozlabs.org>; Tue,  5 May 2026 15:15:03 +0000 (GMT)",
            "from mail-pf1-x429.google.com (mail-pf1-x429.google.com\n [IPv6:2607:f8b0:4864:20::429])\n by sourceware.org (Postfix) with ESMTPS id 3D11F4BA901C\n for <gcc-patches@gcc.gnu.org>; Tue,  5 May 2026 15:10:45 +0000 (GMT)",
            "by mail-pf1-x429.google.com with SMTP id\n d2e1a72fcca58-8270edc7e2eso185039b3a.2\n for <gcc-patches@gcc.gnu.org>; Tue, 05 May 2026 08:10:45 -0700 (PDT)",
            "from waffl3x-prestige.lan ([2001:56a:f98a:b800:1f67:ce08:3cbd:86b8])\n by smtp.gmail.com with ESMTPSA id\n d2e1a72fcca58-83965645140sm2674956b3a.12.2026.05.05.08.10.43\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 05 May 2026 08:10:43 -0700 (PDT)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 5E02A4B9DB40",
            "OpenDKIM Filter v2.11.0 sourceware.org 3D11F4BA901C"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 3D11F4BA901C",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 3D11F4BA901C",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777993845; cv=none;\n b=nwSllDtkvyyVpEOG15KR4dzSAnSfAIYHQhJTAzrykLPJDiQA4Hge9l9m5qq43x2/bVMWwSosCpWHXaHkDjU1UUyqbfbb+oJAGSqBNoAhFyvZZKVmbCIn3Zt6izGEQRdLIQzbjFvUbIIv/819kx3tUwGLo4p9Roi0FdLUVq+48is=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777993845; c=relaxed/simple;\n bh=5MmzDzRbTa1Nc597zcSWr5hq+GLl2pjrNDwxuuud30s=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=AaN5TzdioLhU+0X1ckmWLhbQrKrn/6O0qWYeay5b5jLQ3d4pTCi768+0pSooaii0nypJ5+YsyKWuTZejRmY2xYM/d/iVPd4aNW/AbA+GUoou9REPWmylnST5anuw41dDReLJ6yyaCpcnQdBldvoIE8eBdgU2+sPY9IE3RxdXj3Y=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=baylibre-com.20251104.gappssmtp.com; s=20251104; t=1777993844;\n x=1778598644;\n darn=gcc.gnu.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=/XG/My7MXGpBwVGqzYJsvCW3dOUAxVIVxF90SGgIS9I=;\n b=pgrdbNp/SKEOzopxPVI6WT4deuwLYW1Z1YizBAsv/CGdEUmWwfz1db869N2aY2xNNF\n vPLwoHZ0ViP0OqJoZ414axxUsrDGD5vawCLT+YFQ8qasgUv0H8Gzxo3yEVDCY/CEMyLg\n mRbWeHmhzbVr/3eKwItoUwJ/D8xD9mYtjt3AzlWITSMgx7+yqLZSN4JdIGz7xEG+lWMK\n MPFRa2DJRGJx2CEM8jrmlg+ct5U6oxNx8DZhgyi7acyoNroPpPz/9u8vD0p+xbrjcRpl\n LKBe+Qr8icKx8V3jfgrM3I9nS1ULzAwah4VHBO8W1jXvnoWqq4vy/v9/8FQpvcesmVBz\n +i9g==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777993844; x=1778598644;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=/XG/My7MXGpBwVGqzYJsvCW3dOUAxVIVxF90SGgIS9I=;\n b=DG47WP8J2DGEtJcoMSN+R/yHYW4oIyehk+AKCoqoYaOc2FCUA3Qp1g2TGRBb0oMYQ4\n ZFhF/0ij8eZ+pHz20s2Ip99OVMIO6NR/FZJlZBk5U9rAZv7zBB0g93NxfrNeW8a9R3gs\n xwDCCz3MMJzNsIOpyD2YBKMLXGieO6wjN37E4jg+Rbs8IAo9Ds/q81vlVpKZRys79aWK\n 3azJ37S5SwoG8/S1spm5fdyMAMs6IUmFZqdt6xne72vJkI2HBtJuqWClaQvxnyy1kY6T\n fZERorLh/hINXOdDzWnbk1Tc7860uJFJuP0ZkM23gbUsmfW67VdgkEihprRlcuPeXBEs\n cCdQ==",
        "X-Gm-Message-State": "AOJu0Yw8HkVHoqCUTrW8tmfRlqfRuLOMY+mrlm5kINxxIl/NK86pakEC\n W4eUoWiBq+YRlF7yga/I6jX08I3W2K/+QqKkYL8Do4gCXW5ShFYGt2g0EBxacZQ1K0yHvZbCHf3\n +iKG+",
        "X-Gm-Gg": "AeBDievc3EZUuox5tye1FDDoQODkv91UvYJGZeS5YJVDMYjOH3+L2N8nORpVENkda2O\n ghDW+x7CcxuZ/WeiMwFQE5b2OfkCv+6ioxG6rfcSFwiZu6DovKCsdELZdi5g0ZIfVeygInUqdMv\n TvXOd0nSl76pFOL789/NY7Mv2W3VqVa9BgAHzeJ2gSris1T15BxT835R2zU07n2CQ7DgoTanzfx\n +k5IAoeQG3VSUnQU/Ebo70XZUP5MztbxDUkwI9ED/PigvAviNbdWFurBCYOczVDcc/V4nW8qA5F\n LrN7wp4ozHJYAwORe7EtWp2banm6WaJNzGSA4NKhf5SZ6GWFFEuQlLikTB4Hnl0DvT5aAVSGCeY\n wONy5Mg1kp4kOhRrOs8HrOF7Q5HCsWGwCO7O6N83zw+9Se8zRgHX2uGzK1finmqYt06GKMvvXUP\n 4LVA9jkSx3kEJJ/leI0WRCI7KdUPTwh0CR18dG+n5/932t9LH2mg==",
        "X-Received": "by 2002:a05:6a00:9a8:b0:81f:72ef:27f0 with SMTP id\n d2e1a72fcca58-8393e752930mr1589494b3a.6.1777993844048;\n Tue, 05 May 2026 08:10:44 -0700 (PDT)",
        "From": "Waffl3x <waffl3x@baylibre.com>",
        "To": "gcc-patches@gcc.gnu.org",
        "Cc": "Waffl3x <waffl3x@baylibre.com>",
        "Subject": "[PATCH 08/12] OpenMP/C++: Add static analysis of allocate directive\n allocator clause",
        "Date": "Tue,  5 May 2026 09:02:01 -0600",
        "Message-ID": "<20260505151030.1749548-9-waffl3x@baylibre.com>",
        "X-Mailer": "git-send-email 2.54.0",
        "In-Reply-To": "<20260505151030.1749548-1-waffl3x@baylibre.com>",
        "References": "\n <CAH+W3Ppbho4pj6W-rWk4mMssrttOjt7aNco-oWW5Sw5f5Yx2GA@mail.gmail.com>\n <20260505151030.1749548-1-waffl3x@baylibre.com>",
        "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": "Due to the nature of transformations made on vars in an 'omp allocate'\ndirective, there are additional requirements on an allocator clause\nattached to the directive. At minimum, all vars used in its expr must be\ndeclared before all the vars specified in the allocate directive, this\nalso includes vars used in the directive themselves. This is of course\nunless the vars in the expr are unevaluated or static constexpr.  We could\npotentially allow static but it doesn't seem practical. Allowing constexpr\nvars without static could also be fine if the clause is constant evaluated\nbut that increases complexity. One can still declare such vars before the\nfirst var in the allocate directive.\n\nThis patch diagnoses such cases, and takes into account those exceptions.\nIn the future we could provide better diagnostics for the edge cases, such\nas suggesting adding 'static' to a constexpr variable declaration.\n\nThe C front end also tries to diagnose mutations of such vars that occur\nbetween the first declared variable in the allocate directive and the\nallocate directive itself, but it misses non-trivial cases.  This patch\ndoes not attempt to diagnose these. It would be better to move such\ndiagnostics and warnings into finish_omp_allocate as there are a lot of\ncases that are dependent. The diagnostics of declaration order and bad uses\nof vars can stay in cp_parser_omp_allocate.\n\ngcc/cp/ChangeLog:\n\n\t* parser.cc (cp_parser_omp_allocate): Add allocator clause expr\n\tdiagnostics.\n\ngcc/testsuite/ChangeLog:\n\n\t* c-c++-common/gomp/allocate-5.c: Adjust test.\n\t* c-c++-common/gomp/allocate-12.c: Remove xfail.\n\t* c-c++-common/gomp/allocate-16.c: Likewise.\n\t* c-c++-common/gomp/allocate-20.c: Likewise.\n\t* g++.dg/gomp/allocate-23.C: New test.\n\nSigned-off-by: Waffl3x <waffl3x@baylibre.com>\n---\n gcc/cp/parser.cc                              | 129 ++++++++++++++++++\n gcc/testsuite/c-c++-common/gomp/allocate-12.c |   6 +-\n gcc/testsuite/c-c++-common/gomp/allocate-16.c |   9 +-\n gcc/testsuite/c-c++-common/gomp/allocate-20.c |  12 +-\n gcc/testsuite/c-c++-common/gomp/allocate-5.c  |   5 +-\n gcc/testsuite/g++.dg/gomp/allocate-23.C       |  24 ++++\n 6 files changed, 170 insertions(+), 15 deletions(-)\n create mode 100644 gcc/testsuite/g++.dg/gomp/allocate-23.C",
    "diff": "diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc\nindex 412a71c439c..aa6777e5ed4 100644\n--- a/gcc/cp/parser.cc\n+++ b/gcc/cp/parser.cc\n@@ -47190,6 +47190,10 @@ cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)\n   nl = nreverse (nl);\n \n   const tree directive_ctx = current_scope ();\n+  /* Used for diagnostics of the allocator clause's expr in\n+     check_omp_allocate_allocator_r.  We only keep this locally, nl is still\n+     what ultimately gets passed along to finish_omp_allocate.  */\n+  hash_map<tree, location_t> arg_map;\n   {\n     auto var_is_in_scope = [&] (tree var_decl)\n       {\n@@ -47325,6 +47329,7 @@ cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)\n \t\t\t\t       arg_loc_wrapper,\n \t\t\t\t       *attr_chain);\n \t    }\n+\t    arg_map.put (var, arg_loc);\n \t    /* Keep the node.  */\n \t    chain = &TREE_CHAIN (node);\n \t  }\n@@ -47373,6 +47378,130 @@ cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)\n     } while (true);\n   cp_parser_require_pragma_eol (parser, pragma_tok);\n \n+  /* Used in check_omp_allocate_allocator_r callback.  */\n+  struct omp_alloc_expr_ctx\n+  {\n+    location_t alloc_expr_loc;\n+    tree first_arg;\n+    hash_map<tree, location_t>& arg_map;\n+    hash_set<tree>& declared_after_first_arg;\n+    /* Vars used erroneously in the alloc expr.  */\n+    hash_set<tree> diagnosed;\n+  };\n+  /* Callback for cp_walk_tree.  Always returns NULL_TREE so we diagnose as\n+     much as possible.  */\n+  auto check_omp_allocate_allocator_r = [] (tree *tp, int *ws, void *data)\n+    {\n+      gcc_assert (tp != nullptr && ws != nullptr && data != nullptr);\n+      /* Uses of variables in unevaluated contexts are permitted.  */\n+      if (TREE_CODE (*tp) == DECLTYPE_TYPE)\n+\t{\n+\t  *ws = 0;\n+\t  return NULL_TREE;\n+\t}\n+      /* Unwrap manually so we have a location for diagnostics.  */\n+      tree var_in_expr = tree_strip_any_location_wrapper (*tp);\n+      if (!VAR_P (var_in_expr))\n+\treturn NULL_TREE;\n+      /* We can technically allow more than this, but it gets a bit more hazy.\n+\t In particular just 'static' should be okay, but it would need to be\n+\t constant initialized.  It just doesn't make sense to allow it.\n+\t (It can still be used as long as it is declared before.)  */\n+      if (DECL_DECLARED_CONSTEXPR_P (var_in_expr)\n+\t  && TREE_STATIC (var_in_expr))\n+\treturn NULL_TREE;\n+      /* Don't walk wrappers of vars, unwrap them manually (see above).  */\n+      if (location_wrapper_p (*tp))\n+\t*ws = 0;\n+\n+      omp_alloc_expr_ctx& ctx = *static_cast<omp_alloc_expr_ctx *>(data);\n+      /* Don't repeat diagnostics if we find the same var used twice.  */\n+      if (ctx.diagnosed.contains (var_in_expr))\n+\treturn NULL_TREE;\n+\n+      /* Don't evaluate the location until we need it.  */\n+      auto make_alloc_expr_loc = [&] ()\n+\t{\n+\t  const location_t alloc_expr_loc = ctx.alloc_expr_loc;\n+\t  const location_t loc = EXPR_LOCATION (*tp);\n+\t  /* If *tp has a meaningful location, use it for the caret.  */\n+\t  return loc == UNKNOWN_LOCATION\n+\t\t ? alloc_expr_loc\n+\t\t : make_location (loc, alloc_expr_loc, alloc_expr_loc);\n+\t};\n+\n+      if (const location_t *const arg_loc = ctx.arg_map.get (var_in_expr))\n+\t{\n+\t  auto_diagnostic_group d;\n+\t  error_at (make_alloc_expr_loc (),\n+\t\t    \"variable %qD used in %<allocate%> directive must \"\n+\t\t    \"not be used in its %<allocator%> clause\", var_in_expr);\n+\t  inform (DECL_SOURCE_LOCATION (var_in_expr), \"declared here\");\n+\t  inform (*arg_loc,\n+\t\t  \"used in allocate directive here\");\n+\t  ctx.diagnosed.add (var_in_expr);\n+\t  return NULL_TREE;\n+\t}\n+      if (ctx.declared_after_first_arg.contains (var_in_expr))\n+\t{\n+\t  auto_diagnostic_group d;\n+\t  error_at (make_alloc_expr_loc (),\n+\t\t    \"variable %qD used in the %<allocator%> clause \"\n+\t\t    \"must be declared before %qD\",\n+\t\t    var_in_expr, ctx.first_arg);\n+\t  inform (DECL_SOURCE_LOCATION (var_in_expr), \"declared here\");\n+\t  inform (DECL_SOURCE_LOCATION (ctx.first_arg),\n+\t\t  \"first to be allocated variable declared here\");\n+\t  ctx.diagnosed.add (var_in_expr);\n+\t  return NULL_TREE;\n+\t}\n+      return NULL_TREE;\n+    };\n+\n+  /* Diagnose invalid uses of variables in the allocator clause's expr.\n+     If we want to warn about variables that are potentially modified, either\n+     by their address being taken or a reference being bound, it must be done\n+     in cp/semantics.cc:finish_omp_allocate instead as such cases can\n+     potentially be dependent.  */\n+  if (allocator != NULL_TREE && !arg_map.is_empty ())\n+    {\n+      hash_set<tree> declared_after_first_arg;\n+      const tree first_arg = [&] ()\n+\t{\n+\t  tree var = current_binding_level->names;\n+\t  size_t remaining_args = arg_map.elements ();\n+\t  for (; var != NULL_TREE; var = DECL_CHAIN (var))\n+\t    {\n+\t      gcc_assert (remaining_args != 0);\n+\t      if (!VAR_P (var))\n+\t\tcontinue;\n+\t      if (!arg_map.get (var))\n+\t\t{\n+\t\t  /* We haven't seen every arg in arg_map, this var is declared\n+\t\t     after at least one of the args.  */\n+\t\t  declared_after_first_arg.add (var);\n+\t\t  continue;\n+\t\t}\n+\t      --remaining_args;\n+\t      if (remaining_args == 0)\n+\t\tbreak;\n+\t    }\n+\t  /* We stop the above loop before advancing the chain so VAR is the\n+\t     first variable declared (not to be confused with the first arg)\n+\t     that was passed into the allocate directive.  */\n+\t  return var;\n+\t} (); /* IILE.  */\n+\n+      gcc_assert (first_arg != NULL_TREE && arg_map.get (first_arg));\n+      omp_alloc_expr_ctx ctx = {allocator.get_location (), first_arg, arg_map,\n+\t\t\t\tdeclared_after_first_arg, hash_set<tree>()};\n+      tree a = allocator.get_value ();\n+      cp_walk_tree (&a, check_omp_allocate_allocator_r, &ctx, nullptr);\n+      /* Don't try to do anything else with an invalid allocator expr.  */\n+      if (!ctx.diagnosed.is_empty ())\n+\tallocator = cp_expr (error_mark_node, UNKNOWN_LOCATION);\n+    }\n+\n   /* Some codes, such as template parameters, don't get wrapped by\n      maybe_wrap_with_location despite not being able to carry a location.\n      We need a location to issue good diagnostics in finish_omp_allocate.  */\ndiff --git a/gcc/testsuite/c-c++-common/gomp/allocate-12.c b/gcc/testsuite/c-c++-common/gomp/allocate-12.c\nindex 6a53770697c..6f3ddd361f2 100644\n--- a/gcc/testsuite/c-c++-common/gomp/allocate-12.c\n+++ b/gcc/testsuite/c-c++-common/gomp/allocate-12.c\n@@ -47,9 +47,9 @@ f2 ()\n int\n g ()\n {\n-  int n = 5;  /* { dg-note \"to be allocated variable declared here\" \"\" { xfail c++ } } */\n-  omp_allocator_handle_t my_allocator = omp_low_lat_mem_alloc;  /* { dg-note \"declared here\" \"\" { xfail c++ } } */\n-  #pragma omp allocate(n) allocator(my_allocator)  /* { dg-error \"variable 'my_allocator' used in the 'allocator' clause must be declared before 'n'\" \"\" { xfail c++ } } */\n+  int n = 5;  /* { dg-note \"to be allocated variable declared here\" } */\n+  omp_allocator_handle_t my_allocator = omp_low_lat_mem_alloc;  /* { dg-note \"declared here\" } */\n+  #pragma omp allocate(n) allocator(my_allocator)  /* { dg-error \"variable 'my_allocator' used in the 'allocator' clause must be declared before 'n'\" } */\n   n = 7;\n   return n;\n }\ndiff --git a/gcc/testsuite/c-c++-common/gomp/allocate-16.c b/gcc/testsuite/c-c++-common/gomp/allocate-16.c\nindex 7df9a92fd9f..b5317b575e5 100644\n--- a/gcc/testsuite/c-c++-common/gomp/allocate-16.c\n+++ b/gcc/testsuite/c-c++-common/gomp/allocate-16.c\n@@ -14,15 +14,16 @@ omp_allocator_handle_t foo(int, int *);\n void\n f ()\n {\n-  int v;  /* { dg-note \"to be allocated variable declared here\" \"\" { xfail c++ } } */\n+  int v;  /* { dg-note \"to be allocated variable declared here\" } */\n   static const int n = 5;\n   int a = 1;\n-  /* { dg-note \"declared here\" \"\" { xfail c++ } .-1 } */\n+  /* { dg-note \"declared here\" \"\" { target *-*-* } .-1 } */\n   int b[n];\n-  /* { dg-note \"declared here\" \"\" { target c++ xfail c++ } .-1 } */\n+  /* { dg-note \"declared here\" \"\" { target c++ } .-1 } */\n   b[a] = 5;\n   #pragma omp allocate (v) allocator (foo (a, &b[a]))\n-  /* { dg-error \"variable 'a' used in the 'allocator' clause must be declared before 'v'\" \"\" { xfail c++ } .-1 } */\n+  /* { dg-error \"variable 'a' used in the 'allocator' clause must be declared before 'v'\" \"\" { target *-*-* } .-1 } */\n+  /* { dg-error \"variable 'b' used in the 'allocator' clause must be declared before 'v'\" \"\" { target c++ } .-2 } */\n }\n \n void\ndiff --git a/gcc/testsuite/c-c++-common/gomp/allocate-20.c b/gcc/testsuite/c-c++-common/gomp/allocate-20.c\nindex 604e4847a92..36f3cb3627c 100644\n--- a/gcc/testsuite/c-c++-common/gomp/allocate-20.c\n+++ b/gcc/testsuite/c-c++-common/gomp/allocate-20.c\n@@ -262,8 +262,8 @@ void f_with_parm_and_allocator0(int p) /* { dg-note \"parameter 'p' declared here\n \n void f_with_parm_and_allocator1(int p) /* { dg-note \"parameter 'p' declared here\" \"\" { target c++ } } */\n {\n-  int v0; /* { dg-note \"to be allocated variable declared here\" \"\" { xfail c++ } } */\n-  omp_allocator_handle_t alloc0 = omp_default_mem_alloc; /* { dg-note \"declared here\" \"\" { xfail c++ } } */\n+  int v0; /* { dg-note \"to be allocated variable declared here\" } */\n+  omp_allocator_handle_t alloc0 = omp_default_mem_alloc; /* { dg-note \"declared here\" } */\n   /* { dg-error \"function parameter 'p' may not appear as list item in an 'allocate' directive\" \"\" { target c } .+2 } */\n   /* { dg-error \"variable 'alloc0' used in the 'allocator' clause must be declared before 'v0'\" \"\" { target c } .+1 } */\n   #pragma omp allocate(\\\n@@ -271,7 +271,7 @@ void f_with_parm_and_allocator1(int p) /* { dg-note \"parameter 'p' declared here\n   v0)\\\n   allocator(alloc0)\n   /* { dg-error \"function parameter 'p' may not appear as list item in an 'allocate' directive\" \"\" { target c++ } .-3 } */\n-  /* { dg-error \"variable 'alloc0' used in the 'allocator' clause must be declared before 'v0'\" \"\" { target c++ xfail c++ } .-2 } */\n+  /* { dg-error \"variable 'alloc0' used in the 'allocator' clause must be declared before 'v0'\" \"\" { target c++ } .-2 } */\n \n   int v1; /* { dg-note \"declared here\" } */\n   {\n@@ -285,8 +285,8 @@ void f_with_parm_and_allocator1(int p) /* { dg-note \"parameter 'p' declared here\n     /* { dg-error \"'allocate' directive must be in the same scope as 'v1'\" \"\" { target c++ } .-3 } */\n   }\n   {\n-    int v3; /* { dg-note \"to be allocated variable declared here\" \"\" { xfail c++ } } */\n-    omp_allocator_handle_t alloc2 = omp_default_mem_alloc; /* { dg-note \"declared here\" \"\" { xfail c++ } } */\n+    int v3; /* { dg-note \"to be allocated variable declared here\" } */\n+    omp_allocator_handle_t alloc2 = omp_default_mem_alloc; /* { dg-note \"declared here\" } */\n     /* { dg-error \"variable 'alloc2' used in the 'allocator' clause must be declared before 'v3'\" \"\" { target c } .+2 } */\n     /* { dg-error \"'allocate' directive must be in the same scope as 'v1'\" \"\" { target c } .+1 } */\n     #pragma omp allocate(\\\n@@ -294,7 +294,7 @@ void f_with_parm_and_allocator1(int p) /* { dg-note \"parameter 'p' declared here\n     v3\\\n     ) allocator(alloc2)\n     /* { dg-error \"'allocate' directive must be in the same scope as 'v1'\" \"\" { target c++ } .-3 } */\n-    /* { dg-error \"variable 'alloc2' used in the 'allocator' clause must be declared before 'v3'\" \"\" { target c++ xfail c++ } .-2 } */\n+    /* { dg-error \"variable 'alloc2' used in the 'allocator' clause must be declared before 'v3'\" \"\" { target c++ } .-2 } */\n   }\n }\n \ndiff --git a/gcc/testsuite/c-c++-common/gomp/allocate-5.c b/gcc/testsuite/c-c++-common/gomp/allocate-5.c\nindex b34f9ea9227..e47bfb217bf 100644\n--- a/gcc/testsuite/c-c++-common/gomp/allocate-5.c\n+++ b/gcc/testsuite/c-c++-common/gomp/allocate-5.c\n@@ -39,9 +39,10 @@ bar ()\n   /* { dg-error \"expected end of line before '\\\\(' token\" \"\" { target *-*-* } .-1 } */\n #pragma omp allocate(a2) allocator(b)\n   /* { dg-error \"'allocator' clause expression has type 'int' rather than 'omp_allocator_handle_t'\" \"\" { target c } .-1 } */\n-  /* { dg-error \"invalid conversion from 'int' to 'omp_allocator_handle_t'\" \"\" { target c++ } .-2 } */\n+  /* { dg-error \"variable 'b' used in the 'allocator' clause must be declared before 'a2'\" \"\" { target c++ } .-2 } */\n   /* We have diverging behavior here between c and c++ due to a difference in\n-     order of diagnostics, as well as diverging semantics, this should probably be unified.  */\n+     order of diagnostics, as well as diverging semantics, this should probably be unified.\n+     Really this is probably very bugged in C.  */\n }\n \n \ndiff --git a/gcc/testsuite/g++.dg/gomp/allocate-23.C b/gcc/testsuite/g++.dg/gomp/allocate-23.C\nnew file mode 100644\nindex 00000000000..8593dfcc915\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/gomp/allocate-23.C\n@@ -0,0 +1,24 @@\n+/* { dg-do compile { target c++14 } } */\n+#include \"allocate-allocator-handle.h\"\n+\n+/* Valid uses of vars in an allocator clause.  */\n+\n+void constexpr_var_declared_after()\n+{\n+  int a = 42;\n+  static constexpr omp_allocator_handle_t my_handle = omp_default_mem_alloc;\n+  #pragma omp allocate(a) allocator(my_handle)\n+}\n+\n+template<typename...>\n+constexpr omp_allocator_handle_t get_alloc()\n+{\n+  return omp_default_mem_alloc;\n+}\n+\n+void unevaluated_use_of_var()\n+{\n+  int a = 42;\n+  int b = 42;\n+  #pragma omp allocate(a, b) allocator(get_alloc<decltype(a), decltype(b)>())\n+}\n",
    "prefixes": [
        "08/12"
    ]
}