get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2229918,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2229918/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260428212111.1026503-1-polacek@redhat.com/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/1.1/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
    },
    "msgid": "<20260428212111.1026503-1-polacek@redhat.com>",
    "date": "2026-04-28T21:21:11",
    "name": "c++/reflection: remove cp_preserve_using_decl [PR124169]",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "0a31861a7d1b17c5a8262b2f61f37a3e4fa5f311",
    "submitter": {
        "id": 14370,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/14370/?format=api",
        "name": "Marek Polacek",
        "email": "polacek@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260428212111.1026503-1-polacek@redhat.com/mbox/",
    "series": [
        {
            "id": 501935,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/501935/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=501935",
            "date": "2026-04-28T21:21:11",
            "name": "c++/reflection: remove cp_preserve_using_decl [PR124169]",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/501935/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2229918/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2229918/checks/",
    "tags": {},
    "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 (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=TrbL2hkq;\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 (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=TrbL2hkq",
            "sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com",
            "sourceware.org; spf=pass smtp.mailfrom=redhat.com",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.133.124"
        ],
        "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 4g4tft3pHHz1yK5\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 Apr 2026 07:21:57 +1000 (AEST)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 2E1864BA9010\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 21:21:55 +0000 (GMT)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by sourceware.org (Postfix) with ESMTP id 2875A4BA543C\n for <gcc-patches@gcc.gnu.org>; Tue, 28 Apr 2026 21:21:24 +0000 (GMT)",
            "from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-86-BZ5BpoiMPvOVnYvDT6CS5A-1; Tue,\n 28 Apr 2026 17:21:22 -0400",
            "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 7A7B5195608B\n for <gcc-patches@gcc.gnu.org>; Tue, 28 Apr 2026 21:21:21 +0000 (UTC)",
            "from pdp-11.lan (unknown [10.22.89.17])\n by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id E0B3D195608E; Tue, 28 Apr 2026 21:21:20 +0000 (UTC)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 2E1864BA9010",
            "OpenDKIM Filter v2.11.0 sourceware.org 2875A4BA543C"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 2875A4BA543C",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 2875A4BA543C",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777411284; cv=none;\n b=cCkadjOQAhCsaVdd6XsX37xWF8Wlcm7zKSXeTob/KyctaGE4PL70eqvj0Zk6WsIpHEi9RUf8pEW2dr38DljhZAmmSjepn2DOEgJikscjbHjrdm1rxLmyjctSHGQJJJrv66vOI35lnF+Bj7CbGKs97sgPqoC+SWxj/jxnpBf2wYo=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777411284; c=relaxed/simple;\n bh=E/N/55n2z6hiXt8KWPw++PicLk885QaH/anrjYWqToU=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=NHo8wSW9WHh2Jpt+Jnf++2URYUVR6Hb91+A8xIf3O6FiVqqBdktokyzjTlSqLu/9xeEqfGBkt0rTrusslKNekwflMoqRe1ujuUdLNNMJ92iAY1wZiQr/Z+tJ2cR31abIhlpFzMVIo3tN6O6mgtvU955+PfznkxYnDubWyM5gwHc=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1777411283;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding;\n bh=wKsHkbiqJLw89YY/d9fa+sMHbRfyY8luvegQ2iKFMWI=;\n b=TrbL2hkqZrN7LiQeCtkTv9bCKUNsQTexrnS6/MTvveCYbj0YAdQtZk0UI0u12mTjKKNo/g\n i7JEOaz+iFI4OpoG5w5rAcZWkfK/nRbSwNBfWcm3bXNb6/N/hf64ON8FCMj24W8gf+Aw+J\n gKl9yEOeYXsJAbWD8WovXQQ8YktS57Q=",
        "X-MC-Unique": "BZ5BpoiMPvOVnYvDT6CS5A-1",
        "X-Mimecast-MFC-AGG-ID": "BZ5BpoiMPvOVnYvDT6CS5A_1777411281",
        "From": "Marek Polacek <polacek@redhat.com>",
        "To": "GCC Patches <gcc-patches@gcc.gnu.org>,\n\tJason Merrill <jason@redhat.com>",
        "Subject": "[PATCH] c++/reflection: remove cp_preserve_using_decl [PR124169]",
        "Date": "Tue, 28 Apr 2026 17:21:11 -0400",
        "Message-ID": "<20260428212111.1026503-1-polacek@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "wl7Sfbu2dkE77tg4395syhTMmTLjNguWBj1NqKPV_6A_1777411281",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Transfer-Encoding": "8bit",
        "content-type": "text/plain; charset=\"US-ASCII\"; x-default=true",
        "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": "Frankly I'm not so sure this patch is such a great idea but I had to try.\n\nBootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?\n\n-- >8 --\ncp_preserve_using_decl is too broad so it would be good to have\na LOOK_want instead.  This patch removes the global variable\nand instead adds LOOK_want::KEEP_USING.  This has to be somehow\npropagated from cp_parser_lookup_name all the way down to\nstrip_using_decl.  Unfortunately there are many paths by which\none can get to strip_using_decl, so this patch isn't as small\nas I had hoped.\n\n\tPR c++/124169\n\ngcc/cp/ChangeLog:\n\n\t* cp-tree.h: Remove cp_preserve_using_decl.\n\t(lookup_member): Adjust declaration.\n\t(strip_using_decl): Likewise.\n\t* name-lookup.cc (search_anon_aggr): Make static.  New bool\n\tparameter.  Pass it down to get_class_binding_direct.\n\t(name_lookup::process_binding): Adjust calls to strip_using_decl.\n\t(fields_linear_search): New bool parameter.  Pass it down to\n\tsearch_anon_aggr.  Adjust the call to strip_using_decl.\n\t(name_independent_linear_search): Likewise.\n\t(get_class_binding_direct): New bool parameter.  Pass it down to\n\tname_independent_linear_search and fields_linear_search.\n\t(get_class_binding): New bool parameter.  Pass it down to\n\tget_class_binding_direct.\n\t(strip_using_decl): New bool parameter.  If it's true, don't\n\tstrip USING_DECLs.  Don't check cp_preserve_using_decl.\n\t(lookup_class_binding): Adjust the call to fields_linear_search.\n\t(lookup_qualified_name): Check want instead of\n\tcp_preserve_using_decl.  Adjust the call to lookup_member.\n\t* name-lookup.h (LOOK_want): Add KEEP_USING.\n\t(search_anon_aggr): Remove declaration.\n\t(get_class_binding_direct): Adjust declaration.\n\t(get_class_binding): Likewise.\n\t* parser.cc: Remove cp_preserve_using_decl.\n\t(cp_parser_reflection_name): Don't override\n\tcp_preserve_using_decl.  Call cp_parser_lookup_name instead of\n\tcp_parser_lookup_name_simple.\n\t(cp_parser_lookup_name): New bool parameter.  Use it.  Adjust\n\tcalls to lookup_qualified_name, lookup_member, and lookup_name.\n\t* search.cc (struct lookup_field_info): Add keep_using.\n\t(lookup_field_r): Pass lfi->keep_using to get_class_binding.\n\t(lookup_member): New bool parameter.  Use it to set\n\tlfi.keep_using.  Pass it to strip_using_decl.\n\ngcc/testsuite/ChangeLog:\n\n\t* g++.dg/reflect/expr17.C: New test.\n---\n gcc/cp/cp-tree.h                      |  7 ++-\n gcc/cp/name-lookup.cc                 | 69 ++++++++++++++++-----------\n gcc/cp/name-lookup.h                  |  8 ++--\n gcc/cp/parser.cc                      | 51 ++++++++++++--------\n gcc/cp/search.cc                      | 13 +++--\n gcc/testsuite/g++.dg/reflect/expr17.C | 13 +++++\n 6 files changed, 102 insertions(+), 59 deletions(-)\n create mode 100644 gcc/testsuite/g++.dg/reflect/expr17.C\n\n\nbase-commit: c1977d101524d87642790422134fe170ce00b545",
    "diff": "diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h\nindex 70132b586d8..3c8d68f5b34 100644\n--- a/gcc/cp/cp-tree.h\n+++ b/gcc/cp/cp-tree.h\n@@ -6253,8 +6253,6 @@ extern bool comparing_contracts;\n \n /* In parser.cc.  */\n \n-extern bool cp_preserve_using_decl;\n-\n /* Nonzero if we are parsing an unevaluated operand: an operand to\n    sizeof, typeof, or alignof.  This is a count since operands to\n    sizeof can be nested.  */\n@@ -8338,7 +8336,8 @@ extern tree lookup_field\t\t\t(tree, tree, int, bool);\n extern tree lookup_fnfields\t\t\t(tree, tree, int, tsubst_flags_t);\n extern tree lookup_member\t\t\t(tree, tree, int, bool,\n \t\t\t\t\t\t tsubst_flags_t,\n-\t\t\t\t\t\t access_failure_info *afi = NULL);\n+\t\t\t\t\t\t access_failure_info * = nullptr,\n+\t\t\t\t\t\t bool = false);\n extern tree lookup_member_fuzzy\t\t\t(tree, tree, bool);\n extern tree locate_field_accessor\t\t(tree, tree, bool);\n extern int look_for_overrides\t\t\t(tree, tree);\n@@ -9182,7 +9181,7 @@ extern void process_and_check_pending_immediate_escalating_fns ();\n extern bool is_invisiref_parm \t\t\t(const_tree);\n \n /* in name-lookup.cc */\n-extern tree strip_using_decl                    (tree);\n+extern tree strip_using_decl                    (tree, bool = false);\n extern void diagnose_name_conflict\t\t(tree, tree);\n extern bool dependent_local_decl_p\t\t(tree);\n \ndiff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc\nindex ef844088381..e7e88882703 100644\n--- a/gcc/cp/name-lookup.cc\n+++ b/gcc/cp/name-lookup.cc\n@@ -44,6 +44,7 @@ static name_hint maybe_suggest_missing_std_header (location_t location,\n \t\t\t\t\t\t   tree name);\n static name_hint suggest_alternatives_for_1 (location_t location, tree name,\n \t\t\t\t\t     bool suggest_misspellings);\n+static tree search_anon_aggr (tree, tree, bool, bool);\n \n /* Slots in BINDING_VECTOR.  */\n enum binding_slots\n@@ -754,8 +755,8 @@ name_lookup::process_binding (tree new_val, tree new_type)\n       && (want & LOOK_want::TYPE_NAMESPACE) == LOOK_want::NAMESPACE)\n     new_type = NULL_TREE;\n \n-  new_val = strip_using_decl (new_val);\n-  new_type = strip_using_decl (new_type);\n+  new_val = strip_using_decl (new_val, bool (want & LOOK_want::KEEP_USING));\n+  new_type = strip_using_decl (new_type, bool (want & LOOK_want::KEEP_USING));\n \n   /* Do we really see a value? */\n   if (new_val)\n@@ -1843,10 +1844,11 @@ member_vec_linear_search (vec<tree, va_gc> *member_vec, tree name)\n   return NULL_TREE;\n }\n \n-/* Linear search of (partially ordered) fields of KLASS for NAME.  */\n+/* Linear search of (partially ordered) fields of KLASS for NAME.  KEEP_USING\n+   is true if we shouldn't strip USING_DECLs.  */\n \n static tree\n-fields_linear_search (tree klass, tree name, bool want_type)\n+fields_linear_search (tree klass, tree name, bool want_type, bool keep_using)\n {\n   for (tree fields = TYPE_FIELDS (klass); fields; fields = DECL_CHAIN (fields))\n     {\n@@ -1855,7 +1857,8 @@ fields_linear_search (tree klass, tree name, bool want_type)\n       if (TREE_CODE (decl) == FIELD_DECL\n \t  && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))\n \t{\n-\t  if (tree temp = search_anon_aggr (TREE_TYPE (decl), name, want_type))\n+\t  if (tree temp = search_anon_aggr (TREE_TYPE (decl), name, want_type,\n+\t\t\t\t\t    keep_using))\n \t    return temp;\n \t}\n \n@@ -1864,7 +1867,7 @@ fields_linear_search (tree klass, tree name, bool want_type)\n \n       if (TREE_CODE (decl) == USING_DECL)\n \t{\n-\t  decl = strip_using_decl (decl);\n+\t  decl = strip_using_decl (decl, keep_using);\n \t  if (is_overloaded_fn (decl))\n \t    continue;\n \t}\n@@ -1887,10 +1890,11 @@ fields_linear_search (tree klass, tree name, bool want_type)\n \n /* Like fields_linear_search, but specific for \"_\" name.  There can be multiple\n    name-independent non-static data members and in that case a TREE_LIST with the\n-   ambiguous decls should be returned.  */\n+   ambiguous decls should be returned.  KEEP_USING is true if we shouldn't strip\n+   USING_DECLs.  */\n \n static tree\n-name_independent_linear_search (tree val, tree klass, tree name)\n+name_independent_linear_search (tree val, tree klass, tree name, bool keep_using)\n {\n   for (tree fields = TYPE_FIELDS (klass); fields; fields = DECL_CHAIN (fields))\n     {\n@@ -1899,7 +1903,8 @@ name_independent_linear_search (tree val, tree klass, tree name)\n       if (TREE_CODE (decl) == FIELD_DECL\n \t  && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))\n \t{\n-\t  if (tree temp = search_anon_aggr (TREE_TYPE (decl), name, false))\n+\t  if (tree temp = search_anon_aggr (TREE_TYPE (decl), name,\n+\t\t\t\t\t    /*want_type=*/false, keep_using))\n \t    {\n \t      decl = temp;\n \t      goto add;\n@@ -1911,7 +1916,7 @@ name_independent_linear_search (tree val, tree klass, tree name)\n \n       if (TREE_CODE (decl) == USING_DECL)\n \t{\n-\t  decl = strip_using_decl (decl);\n+\t  decl = strip_using_decl (decl, keep_using);\n \t  if (is_overloaded_fn (decl))\n \t    continue;\n \t}\n@@ -1953,25 +1958,26 @@ name_independent_linear_search (tree val, tree klass, tree name)\n /* Look for NAME member inside of anonymous aggregate ANON.  Although\n    such things should only contain FIELD_DECLs, we check that too\n    late, and would give very confusing errors if we weren't\n-   permissive here.  */\n+   permissive here.  If KEEP_USING is true, name lookup will preserve\n+   USING_DECLs.  */\n \n-tree\n-search_anon_aggr (tree anon, tree name, bool want_type)\n+static tree\n+search_anon_aggr (tree anon, tree name, bool want_type, bool keep_using)\n {\n   gcc_assert (COMPLETE_TYPE_P (anon));\n-  tree ret = get_class_binding_direct (anon, name, want_type);\n+  tree ret = get_class_binding_direct (anon, name, want_type, keep_using);\n   return ret;\n }\n \n /* Look for NAME as an immediate member of KLASS (including\n-   anon-members or unscoped enum member).  TYPE_OR_FNS is zero for\n-   regular search.  >0 to get a type binding (if there is one) and <0\n-   if you want (just) the member function binding.\n+   anon-members or unscoped enum member).  If KEEP_USING is true,\n+   name lookup will preserve USING_DECLs.\n \n    Use this if you do not want lazy member creation.  */\n \n tree\n-get_class_binding_direct (tree klass, tree name, bool want_type)\n+get_class_binding_direct (tree klass, tree name, bool want_type/*=false*/,\n+\t\t\t  bool keep_using/*=false*/)\n {\n   gcc_checking_assert (RECORD_OR_UNION_TYPE_P (klass));\n \n@@ -2042,11 +2048,12 @@ get_class_binding_direct (tree klass, tree name, bool want_type)\n \tval = member_vec_linear_search (member_vec, lookup);\n \n       if (id_equal (lookup, \"_\") && !want_type)\n-\tval = name_independent_linear_search (val, klass, lookup);\n+\tval = name_independent_linear_search (val, klass, lookup, keep_using);\n       else if (!val || (TREE_CODE (val) == OVERLOAD && OVL_DEDUP_P (val)))\n \t/* Dependent using declarations are a 'field', make sure we\n \t   return that even if we saw an overload already.  */\n-\tif (tree field_val = fields_linear_search (klass, lookup, want_type))\n+\tif (tree field_val = fields_linear_search (klass, lookup, want_type,\n+\t\t\t\t\t\t   keep_using))\n \t  {\n \t    if (!val)\n \t      val = field_val;\n@@ -2108,14 +2115,15 @@ maybe_lazily_declare (tree klass, tree name)\n    special function creation as necessary.  */\n \n tree\n-get_class_binding (tree klass, tree name, bool want_type /*=false*/)\n+get_class_binding (tree klass, tree name, bool want_type/*=false*/,\n+\t\t   bool keep_using/*=false*/)\n {\n   klass = complete_type (klass);\n \n   if (COMPLETE_TYPE_P (klass))\n     maybe_lazily_declare (klass, name);\n \n-  return get_class_binding_direct (klass, name, want_type);\n+  return get_class_binding_direct (klass, name, want_type, keep_using);\n }\n \n /* Find the slot containing overloads called 'NAME'.  If there is no\n@@ -2766,18 +2774,19 @@ pop_bindings_and_leave_scope (void)\n   leave_scope ();\n }\n \n-/* Strip non dependent using declarations. If DECL is dependent,\n-   surreptitiously create a typename_type and return it.  */\n+/* Strip non dependent using declarations.  If DECL is dependent,\n+   surreptitiously create a typename_type and return it.  If\n+   KEEP_USING is true, don't actually strip USING_DECLs.  */\n \n tree\n-strip_using_decl (tree decl)\n+strip_using_decl (tree decl, bool keep_using/*=false*/)\n {\n   if (decl == NULL_TREE)\n     return NULL_TREE;\n \n   while (TREE_CODE (decl) == USING_DECL\n \t && !DECL_DEPENDENT_P (decl)\n-\t && (LIKELY (!cp_preserve_using_decl)\n+\t && (LIKELY (!keep_using)\n \t     || TREE_CODE (USING_DECL_DECLS (decl)) == NAMESPACE_DECL))\n     decl = USING_DECL_DECLS (decl);\n \n@@ -4326,7 +4335,8 @@ lookup_class_binding (tree klass, tree name)\n     {\n       gcc_checking_assert (IS_FAKE_BASE_TYPE (klass)\n \t\t\t   || TYPE_PTRMEMFUNC_P (klass));\n-      found = fields_linear_search (klass, name, false);\n+      found = fields_linear_search (klass, name, /*want_type=*/false,\n+\t\t\t\t    /*keep_using=*/false);\n     }\n \n   return found;\n@@ -7714,7 +7724,7 @@ lookup_qualified_name (tree scope, tree name, LOOK_want want, bool complain)\n \t     for using decls.  */\n \t  if (TREE_CODE (t) == OVERLOAD\n \t      && TREE_TYPE (t) != unknown_type_node\n-\t      && LIKELY (!cp_preserve_using_decl))\n+\t      && LIKELY (!bool (want & LOOK_want::KEEP_USING)))\n \t    t = OVL_FUNCTION (t);\n \t}\n     }\n@@ -7722,7 +7732,8 @@ lookup_qualified_name (tree scope, tree name, LOOK_want want, bool complain)\n     t = lookup_enumerator (scope, name);\n   else if (is_class_type (scope, complain))\n     t = lookup_member (scope, name, 2, bool (want & LOOK_want::TYPE),\n-\t\t       tf_warning_or_error);\n+\t\t       tf_warning_or_error, /*access_failure_info=*/nullptr,\n+\t\t       bool (want & LOOK_want::KEEP_USING));\n \n   if (!t)\n     return error_mark_node;\ndiff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h\nindex cd0799a80de..e2dc0f1aa0f 100644\n--- a/gcc/cp/name-lookup.h\n+++ b/gcc/cp/name-lookup.h\n@@ -431,6 +431,7 @@ enum class LOOK_want\n \n   ANY_REACHABLE = 1 << 5,  /* Include reachable module declarations not\n \t\t\t      normally visible to name lookup.  */\n+  KEEP_USING = 1 << 6,\t   /* Don't strip USING_DECLs.  */\n \n   TYPE_NAMESPACE = TYPE | NAMESPACE,  /* Either NAMESPACE or TYPE.  */\n };\n@@ -489,9 +490,10 @@ extern void do_namespace_alias (location_t, tree, tree);\n extern tree do_class_using_decl (tree, tree);\n extern tree lookup_arg_dependent (tree, tree, vec<tree, va_gc> *,\n \t\t\t\t  bool tentative = false);\n-extern tree search_anon_aggr (tree, tree, bool = false);\n-extern tree get_class_binding_direct (tree, tree, bool want_type = false);\n-extern tree get_class_binding (tree, tree, bool want_type = false);\n+extern tree get_class_binding_direct (tree, tree, bool want_type = false,\n+\t\t\t\t      bool keep_using = false);\n+extern tree get_class_binding (tree, tree, bool want_type = false,\n+\t\t\t       bool keep_using = false);\n extern tree *find_member_slot (tree klass, tree name);\n extern tree *add_member_slot (tree klass, tree name);\n extern void resort_type_member_vec (void *, void *,\ndiff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc\nindex dc67cfd9f7c..6f2c5eccad3 100644\n--- a/gcc/cp/parser.cc\n+++ b/gcc/cp/parser.cc\n@@ -295,10 +295,6 @@ static FILE *cp_lexer_debug_stream;\n    sizeof, typeof, or alignof.  */\n int cp_unevaluated_operand;\n \n-/* Nonzero if we are parsing a reflect-expression and shouldn't strip\n-   using-declarations.  */\n-bool cp_preserve_using_decl;\n-\n #if ENABLE_ANALYZER\n \n namespace ana {\n@@ -3066,7 +3062,8 @@ static tree cp_parser_objc_struct_declaration\n /* Utility Routines */\n \n static cp_expr cp_parser_lookup_name\n-  (cp_parser *, tree, enum tag_types, int, bool, bool, tree *, location_t);\n+  (cp_parser *, tree, enum tag_types, int, bool, bool, tree *, location_t,\n+   bool = false);\n static tree cp_parser_lookup_name_simple\n   (cp_parser *, tree, location_t);\n static tree cp_parser_maybe_treat_template_as_class\n@@ -10059,11 +10056,15 @@ cp_parser_reflection_name (cp_parser *parser)\n     cp_parser_error (parser, \"%<template%> must follow a nested-name-\"\n \t\t     \"specifier\");\n \n-  auto s = make_temp_override (cp_preserve_using_decl, true);\n   /* Look for the identifier.  */\n   location_t loc = cp_lexer_peek_token (parser->lexer)->location;\n   tree name = cp_parser_identifier (parser);\n-  tree decl = cp_parser_lookup_name_simple (parser, name, loc);\n+  tree decl = cp_parser_lookup_name (parser, name, none_type,\n+\t\t\t\t     /*is_template=*/false,\n+\t\t\t\t     /*is_namespace=*/false,\n+\t\t\t\t     /*check_dependency=*/true,\n+\t\t\t\t     /*ambiguous_decls=*/nullptr,\n+\t\t\t\t     loc, /*keep_using=*/true);\n   if (name != error_mark_node && decl == error_mark_node)\n     cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, loc);\n \n@@ -35255,7 +35256,9 @@ prefer_type_arg (tag_types tag_type)\n \n    If AMBIGUOUS_DECLS is non-NULL, *AMBIGUOUS_DECLS is set to a\n    TREE_LIST of candidates if name-lookup results in an ambiguity, and\n-   NULL_TREE otherwise.  */\n+   NULL_TREE otherwise.\n+\n+   If KEEP_USING is true, name lookup will preserve USING_DECLs.  */\n \n static cp_expr\n cp_parser_lookup_name (cp_parser *parser, tree name,\n@@ -35264,10 +35267,21 @@ cp_parser_lookup_name (cp_parser *parser, tree name,\n \t\t       bool is_namespace,\n \t\t       bool check_dependency,\n \t\t       tree *ambiguous_decls,\n-\t\t       location_t name_location)\n+\t\t       location_t name_location,\n+\t\t       bool keep_using/*=false*/)\n {\n   tree decl;\n   tree object_type = parser->context->object_type;\n+  /* Prepare the want flags.  */\n+  const auto want = (keep_using\n+\t\t     ? prefer_type_arg (tag_type) | LOOK_want::KEEP_USING\n+\t\t     : prefer_type_arg (tag_type));\n+  const auto want_ns = (keep_using\n+\t\t\t? LOOK_want::NAMESPACE | LOOK_want::KEEP_USING\n+\t\t\t: LOOK_want::NAMESPACE);\n+  const auto want_type = (keep_using\n+\t\t\t  ? LOOK_want::TYPE | LOOK_want::KEEP_USING\n+\t\t\t  : LOOK_want::TYPE);\n \n   /* Assume that the lookup will be unambiguous.  */\n   if (ambiguous_decls)\n@@ -35365,8 +35379,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,\n \t     may be instantiated during name lookup.  In that case,\n \t     errors may be issued.  Even if we rollback the current\n \t     tentative parse, those errors are valid.  */\n-\t  decl = lookup_qualified_name (parser->scope, name,\n-\t\t\t\t\tprefer_type_arg (tag_type),\n+\t  decl = lookup_qualified_name (parser->scope, name, want,\n \t\t\t\t\t/*complain=*/true);\n \n \t  /* 3.4.3.1: In a lookup in which the constructor is an acceptable\n@@ -35387,8 +35400,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,\n \t      && DECL_SELF_REFERENCE_P (decl)\n \t      && same_type_p (DECL_CONTEXT (decl), parser->scope))\n \t    decl = lookup_qualified_name (parser->scope, ctor_identifier,\n-\t\t\t\t\t  prefer_type_arg (tag_type),\n-\t\t\t\t\t  /*complain=*/true);\n+\t\t\t\t\t  want, /*complain=*/true);\n \n \t  if (pushed_scope)\n \t    pop_scope (pushed_scope);\n@@ -35443,7 +35455,9 @@ cp_parser_lookup_name (cp_parser *parser, tree name,\n \t\t\t      name,\n \t\t\t      /*protect=*/2,\n \t\t\t      /*prefer_type=*/tag_type != none_type,\n-\t\t\t      tf_warning_or_error);\n+\t\t\t      tf_warning_or_error,\n+\t\t\t      /*access_failure_info=*/nullptr,\n+\t\t\t      keep_using);\n       else\n \tdecl = NULL_TREE;\n \n@@ -35457,13 +35471,13 @@ cp_parser_lookup_name (cp_parser *parser, tree name,\n       else if (!decl)\n \t/* Look it up in the enclosing context.  DR 141: When looking for a\n \t   template-name after -> or ., only consider class templates.  */\n-\tdecl = lookup_name (name, is_namespace ? LOOK_want::NAMESPACE\n+\tdecl = lookup_name (name, is_namespace ? want_ns\n \t\t\t    /* DR 141: When looking in the\n \t\t\t       current enclosing context for a\n \t\t\t       template-name after -> or ., only\n \t\t\t       consider class templates.  */\n-\t\t\t    : is_template ? LOOK_want::TYPE\n-\t\t\t    : prefer_type_arg (tag_type));\n+\t\t\t    : is_template ? want_type\n+\t\t\t    : want);\n \n       /* If we did unqualified lookup of a dependent member-qualified name and\n \t found something, do we want to use it?  P1787 clarified that we need\n@@ -35494,8 +35508,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,\n     }\n   else\n     {\n-      decl = lookup_name (name, is_namespace ? LOOK_want::NAMESPACE\n-\t\t\t  : prefer_type_arg (tag_type));\n+      decl = lookup_name (name, is_namespace ? want_ns : want);\n       parser->qualifying_scope = NULL_TREE;\n       parser->object_scope = NULL_TREE;\n     }\ndiff --git a/gcc/cp/search.cc b/gcc/cp/search.cc\nindex e098362fed7..b55bf042901 100644\n--- a/gcc/cp/search.cc\n+++ b/gcc/cp/search.cc\n@@ -995,6 +995,8 @@ struct lookup_field_info {\n   tree ambiguous;\n   /* If nonzero, we are looking for types, not data members.  */\n   int want_type;\n+  /* If true, we don't strip USING_DECLs.  */\n+  bool keep_using;\n };\n \n /* True for a class member means that it is shared between all objects\n@@ -1072,7 +1074,7 @@ lookup_field_r (tree binfo, void *data)\n       && !BINFO_VIRTUAL_P (binfo))\n     return dfs_skip_bases;\n \n-  nval = get_class_binding (type, lfi->name, lfi->want_type);\n+  nval = get_class_binding (type, lfi->name, lfi->want_type, lfi->keep_using);\n \n   /* If there is no declaration with the indicated name in this type,\n      then there's nothing to do.  */\n@@ -1166,7 +1168,8 @@ build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)\n    ambiguous lookup, we return NULL.  If PROTECT is 1, we issue error\n    messages about inaccessible or ambiguous lookup.  If PROTECT is 2,\n    we return a TREE_LIST whose TREE_TYPE is error_mark_node and whose\n-   TREE_VALUEs are the list of ambiguous candidates.\n+   TREE_VALUEs are the list of ambiguous candidates.  If KEEP_USING is\n+   true, name lookup will preserve USING_DECLs.\n \n    WANT_TYPE is 1 when we should only return TYPE_DECLs.\n \n@@ -1176,7 +1179,8 @@ build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)\n \n tree\n lookup_member (tree xbasetype, tree name, int protect, bool want_type,\n-\t       tsubst_flags_t complain, access_failure_info *afi /* = NULL */)\n+\t       tsubst_flags_t complain, access_failure_info *afi/*=nullptr*/,\n+\t       bool keep_using/*=false*/)\n {\n   tree rval, rval_binfo = NULL_TREE;\n   tree type = NULL_TREE, basetype_path = NULL_TREE;\n@@ -1227,6 +1231,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type,\n   lfi.type = type;\n   lfi.name = name;\n   lfi.want_type = want_type;\n+  lfi.keep_using = keep_using;\n   dfs_walk_all (basetype_path, &lookup_field_r, NULL, &lfi);\n   rval = lfi.rval;\n   rval_binfo = lfi.rval_binfo;\n@@ -1276,7 +1281,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type,\n   if (protect == 1 && !really_overloaded_fn (rval))\n     {\n       tree decl = is_overloaded_fn (rval) ? get_first_fn (rval) : rval;\n-      decl = strip_using_decl (decl);\n+      decl = strip_using_decl (decl, keep_using);\n       /* A dependent USING_DECL will be checked after tsubsting.  */\n       if (TREE_CODE (decl) != USING_DECL\n \t  && !DECL_IOBJ_MEMBER_FUNCTION_P (decl)\ndiff --git a/gcc/testsuite/g++.dg/reflect/expr17.C b/gcc/testsuite/g++.dg/reflect/expr17.C\nnew file mode 100644\nindex 00000000000..c56f45c3912\n--- /dev/null\n+++ b/gcc/testsuite/g++.dg/reflect/expr17.C\n@@ -0,0 +1,13 @@\n+// PR c++/124169\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+enum class Jazz { BOP };\n+using Jazz::BOP;\n+constexpr auto r = ^^BOP;   // { dg-error \"cannot be applied to a using-declaration\" }\n+\n+struct A { enum Mode { Phrygian }; };\n+struct B : A { using A::Phrygian; };\n+struct C : A { using A::Mode; };\n+constexpr auto r2 = ^^B::Phrygian;    // { dg-error \"cannot be applied to a using-declaration\" }\n+constexpr auto r3 = ^^C::Mode;\t      // { dg-error \"cannot be applied to a using-declaration\" }\n",
    "prefixes": []
}