Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2196507/?format=api
{ "id": 2196507, "url": "http://patchwork.ozlabs.org/api/patches/2196507/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/aZBOMt5AxHHn3Qvu@tucnak/", "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": "<aZBOMt5AxHHn3Qvu@tucnak>", "list_archive_url": null, "date": "2026-02-14T10:28:02", "name": "c++: For reflection look through DECL_LOCAL_DECL_P decls and fix up has_default_argument [PR123612]", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "097f6f73f5b0fdbe7e93777749848618d3296b2c", "submitter": { "id": 671, "url": "http://patchwork.ozlabs.org/api/people/671/?format=api", "name": "Jakub Jelinek", "email": "jakub@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/aZBOMt5AxHHn3Qvu@tucnak/mbox/", "series": [ { "id": 492167, "url": "http://patchwork.ozlabs.org/api/series/492167/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=492167", "date": "2026-02-14T10:28:02", "name": "c++: For reflection look through DECL_LOCAL_DECL_P decls and fix up has_default_argument [PR123612]", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/492167/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2196507/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2196507/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 (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=dxvSIV95;\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 (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=dxvSIV95", "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\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 4fClcn3gw0z1xpl\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 14 Feb 2026 21:28:41 +1100 (AEDT)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 142E24BAD14D\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 14 Feb 2026 10:28:39 +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 9DF674BA23D6\n for <gcc-patches@gcc.gnu.org>; Sat, 14 Feb 2026 10:28:09 +0000 (GMT)", "from mx-prod-mc-03.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-450-ZnGXC4w3PpGzvoEQwiq5RQ-1; Sat,\n 14 Feb 2026 05:28:07 -0500", "from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93])\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-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 8070219560B5\n for <gcc-patches@gcc.gnu.org>; Sat, 14 Feb 2026 10:28:06 +0000 (UTC)", "from tucnak.zalov.cz (unknown [10.44.32.49])\n by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with\n ESMTPS\n id AF18C18004AD; Sat, 14 Feb 2026 10:28:05 +0000 (UTC)", "from tucnak.zalov.cz (localhost [127.0.0.1])\n by tucnak.zalov.cz (8.18.1/8.18.1) with ESMTPS id 61EAS2Yr1331066\n (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT);\n Sat, 14 Feb 2026 11:28:02 +0100", "(from jakub@localhost)\n by tucnak.zalov.cz (8.18.1/8.18.1/Submit) id 61EAS2qP1331065;\n Sat, 14 Feb 2026 11:28:02 +0100" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org 142E24BAD14D", "OpenDKIM Filter v2.11.0 sourceware.org 9DF674BA23D6" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 9DF674BA23D6", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 9DF674BA23D6", "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1771064889; cv=none;\n b=Hw2LcLOLKJIS3FzctMli5tjEZmid2BXDLxQ3Y7Acbi5AMjqPbO1okgCeCkJTVqDparzDBqlinYpUlI4WfWO+yvp0Epkcu7nxtCqvNn+rLBJ2kjMABXtRIy6uTL9a3DWfPzRug5VZAww2chRaGEChYEVbm5z7txGNQm0X5WxdMws=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1771064889; c=relaxed/simple;\n bh=me2CN3wG++HHXZFZHPETY3gD0FnbI7JThyMHE7kmegs=;\n h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version;\n b=uqkveekT+XUzZyMM/GXYtq4lvxmofkOVWCPUTupPSJCbfHA7fL5NIQ8dVfvz34s6rjc9K78xXFLF5cqJWIem8z4MFKfRZVVe3mM0HvYsRhc57gn16QwX4vod7bkogyFqxf2n7Cf5Y1JWmnNZZbBMT9MF7Ol5zFET3V/o4F8DjUo=", "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=1771064889;\n h=from:from:reply-to:reply-to:subject:subject:date:date:\n message-id:message-id:to:to:cc:cc:mime-version:mime-version:\n content-type:content-type; bh=SQRTZ/uFTzMXUrvaoUnlQON577Bb1oqDYDhqiiO2fps=;\n b=dxvSIV95V13ZNePgMG9i+2TJ6efU5Ck0cegqioK8WbKuJf5TtreicrtHyJdP1C/TKTdm+U\n yCzr1zwEh/QpdUrg+HHXZBFNeB0y4iDdQydaHGNRdRHBopLfdY2AjyyNEY6+Exfbz+GtxA\n 0yOayIRdnP4HgQdUVyaEj3Kj06WLyVo=", "X-MC-Unique": "ZnGXC4w3PpGzvoEQwiq5RQ-1", "X-Mimecast-MFC-AGG-ID": "ZnGXC4w3PpGzvoEQwiq5RQ_1771064886", "Date": "Sat, 14 Feb 2026 11:28:02 +0100", "From": "Jakub Jelinek <jakub@redhat.com>", "To": "Jason Merrill <jason@redhat.com>, Marek Polacek <polacek@redhat.com>", "Cc": "gcc-patches@gcc.gnu.org", "Subject": "[PATCH] c++: For reflection look through DECL_LOCAL_DECL_P decls and\n fix up has_default_argument [PR123612]", "Message-ID": "<aZBOMt5AxHHn3Qvu@tucnak>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.93", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "taDNjml81C8Vx87FXDPXb8wfaBSEUe6gwWX0D3uywOA_1771064886", "X-Mimecast-Originator": "redhat.com", "Content-Type": "text/plain; charset=us-ascii", "Content-Disposition": "inline", "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": "Jakub Jelinek <jakub@redhat.com>", "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org" }, "content": "Hi!\n\nBased on discussions in the PR that C++ 26 reflection is\nentity based rather than declaration based, the following patch\nensures we reflect DECL_LOCAL_DECL_ALIAS of DECL_LOCAL_DECL_P vars\nor function decls.\nAdditionally, while default arguments are intentionally not merged\nfrom the block scope externs to their corresponding namespace scope\nfunction decls, for std::meta::has_default_argument the wording\nrequires to return true even if there is at least one block scope\nextern with default argument for the particular parameter.\nSo, the patch also records in a new flag whether a default argument\nhas been present in a block scope extern and propagates it through\nfurther duplicate_decls. eval_has_default_arguments then uses\nboth this new flag (for the block scope externs) and the preexisting\nsearch for default arguments in the corresponding type.\n\nBootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?\n\n2026-02-14 Jakub Jelinek <jakub@redhat.com>\n\n\tPR c++/123612\n\t* cp-tree.h (DECL_HAS_DEFAULT_ARGUMENT_P): Define.\n\t* decl.cc (merge_decl_arguments): For -freflection and\n\textern_alias set DECL_HAS_DEFAULT_ARGUMENT_P (oldarg)\n\tif newdecl has a default argument for that parameter,\n\totherwise propagate the flag.\n\t* reflect.cc (get_reflection): For DECL_LOCAL_DECL_P\n\tuse its DECL_LOCAL_DECL_ALIAS.\n\t(eval_has_default_argument): Return boolean_true_node\n\talso if DECL_HAS_DEFAULT_ARGUMENT_P flag is set.\n\n\t* g++.dg/reflect/pr123612.C: New test.\n\n\n\tJakub", "diff": "--- gcc/cp/cp-tree.h.jj\t2026-02-13 10:32:21.490992631 +0100\n+++ gcc/cp/cp-tree.h\t2026-02-13 17:42:08.816452620 +0100\n@@ -532,6 +532,7 @@ extern GTY(()) tree cp_global_trees[CPTI\n FNDECL_MANIFESTLY_CONST_EVALUATED (in FUNCTION_DECL)\n TARGET_EXPR_INTERNAL_P (in TARGET_EXPR)\n CONTRACT_CONST (in ASSERTION_, PRECONDITION_, POSTCONDITION_STMT)\n+ DECL_HAS_DEFAULT_ARGUMENT_P (in PARM_DECL)\n 5: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)\n FUNCTION_RVALUE_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE)\n CALL_EXPR_REVERSE_ARGS (in CALL_EXPR, AGGR_INIT_EXPR)\n@@ -5329,6 +5330,12 @@ get_vec_init_expr (tree t)\n #define MULTIPLE_NAMES_PARM_P(NODE) \\\n TREE_LANG_FLAG_2 (PARM_DECL_CHECK (NODE))\n \n+/* Nonzero for PARM_DECL node means that at least one of block scope externs\n+ for the corresponding FUNCTION_DECL provided default argument for this\n+ parameter. */\n+#define DECL_HAS_DEFAULT_ARGUMENT_P(NODE) \\\n+ TREE_LANG_FLAG_4 (PARM_DECL_CHECK (NODE))\n+\n /* Nonzero for a FIELD_DECL who's NSMDI is currently being\n instantiated. */\n #define DECL_INSTANTIATING_NSDMI_P(NODE) \\\n--- gcc/cp/decl.cc.jj\t2026-02-12 18:49:18.464869512 +0100\n+++ gcc/cp/decl.cc\t2026-02-13 18:01:34.745792786 +0100\n@@ -1792,7 +1792,10 @@ void\n merge_decl_arguments (tree newdecl, tree olddecl, bool new_defines_function,\n \t\t bool types_match, bool extern_alias)\n {\n- tree oldarg, newarg;\n+ tree oldarg, newarg, type = NULL_TREE;\n+ tree first_user_parm = NULL_TREE;\n+ if (extern_alias)\n+ first_user_parm = FUNCTION_FIRST_USER_PARM (newdecl);\n for (oldarg = DECL_ARGUMENTS (olddecl), newarg = DECL_ARGUMENTS (newdecl);\n oldarg && newarg;\n oldarg = DECL_CHAIN (oldarg), newarg = DECL_CHAIN (newarg))\n@@ -1813,6 +1816,27 @@ merge_decl_arguments (tree newdecl, tree\n \t we should do that for the function itself, not just parameters. */\n if (!extern_alias || flag_reflection)\n \tDECL_ATTRIBUTES (oldarg) = DECL_ATTRIBUTES (newarg);\n+ if (!flag_reflection)\n+\tcontinue;\n+ /* For extern_alias set DECL_HAS_DEFAULT_ARGUMENT_P on oldarg\n+\t if the local extern has a default argument for that parameter. */\n+ if (extern_alias)\n+\t{\n+\t if (newarg == first_user_parm)\n+\t type = FUNCTION_FIRST_USER_PARMTYPE (newdecl);\n+\t else if (type)\n+\t type = TREE_CHAIN (type);\n+\t if (type && TREE_PURPOSE (type))\n+\t DECL_HAS_DEFAULT_ARGUMENT_P (oldarg) = 1;\n+\t}\n+ else\n+\t{\n+\t /* Otherwise propagate the flag. */\n+\t if (DECL_HAS_DEFAULT_ARGUMENT_P (oldarg))\n+\t DECL_HAS_DEFAULT_ARGUMENT_P (newarg) = 1;\n+\t if (DECL_HAS_DEFAULT_ARGUMENT_P (newarg))\n+\t DECL_HAS_DEFAULT_ARGUMENT_P (oldarg) = 1;\n+\t}\n /* Merge names for std::meta::has_identifier and\n \t std::meta::{,u8}identifier_of purposes. If they are different and\n \t both oldarg and newarg are named, add flag to force that\n@@ -1820,7 +1844,7 @@ merge_decl_arguments (tree newdecl, tree\n \t unnamed, if neither is a olddecl nor newdecl is definition, propagate\n \t DECL_NAME to both. Otherwise stash the old name into \"old parm name\"\n \t artificial attribute. */\n- if (flag_reflection && DECL_NAME (oldarg) != DECL_NAME (newarg))\n+ if (DECL_NAME (oldarg) != DECL_NAME (newarg))\n \t{\n \t if (DECL_NAME (oldarg) && DECL_NAME (newarg))\n \t {\n--- gcc/cp/reflect.cc.jj\t2026-02-13 16:10:49.053338387 +0100\n+++ gcc/cp/reflect.cc\t2026-02-13 17:50:54.317592740 +0100\n@@ -235,6 +235,10 @@ get_reflection (location_t loc, tree t,\n \tt = dtor;\n }\n \n+ /* Look through block scope externs. */\n+ if (VAR_OR_FUNCTION_DECL_P (t) && DECL_LOCAL_DECL_P (t))\n+ t = DECL_LOCAL_DECL_ALIAS (t);\n+\n if (t == error_mark_node)\n return error_mark_node;\n \n@@ -1708,6 +1712,8 @@ eval_has_default_argument (tree r, refle\n if (eval_is_function_parameter (r, kind) == boolean_false_node)\n return boolean_false_node;\n r = maybe_update_function_parm (r);\n+ if (DECL_HAS_DEFAULT_ARGUMENT_P (r))\n+ return boolean_true_node;\n tree fn = DECL_CONTEXT (r);\n tree args = FUNCTION_FIRST_USER_PARM (fn);\n tree types = FUNCTION_FIRST_USER_PARMTYPE (fn);\n--- gcc/testsuite/g++.dg/reflect/pr123612.C.jj\t2026-02-13 18:31:24.571629423 +0100\n+++ gcc/testsuite/g++.dg/reflect/pr123612.C\t2026-02-13 18:31:11.731845659 +0100\n@@ -0,0 +1,45 @@\n+// PR c++/123612\n+// { dg-do compile { target c++26 } }\n+// { dg-additional-options \"-freflection\" }\n+\n+#include <meta>\n+\n+int a;\n+extern int b;\n+int foo (int x, int y, int z = 42);\n+\n+consteval auto\n+bar ()\n+{\n+ extern int a;\n+ return ^^a;\n+}\n+\n+consteval auto\n+baz ()\n+{\n+ extern int b;\n+ return ^^b;\n+}\n+\n+consteval auto\n+qux ()\n+{\n+ static_assert (!has_default_argument (parameters_of (^^foo)[0]));\n+ static_assert (!has_default_argument (parameters_of (^^foo)[1]));\n+ static_assert (has_default_argument (parameters_of (^^foo)[2]));\n+ {\n+ extern int foo (int x, int y = 5, int z = 16);\n+ static_assert (!has_default_argument (parameters_of (^^foo)[0]));\n+ static_assert (has_default_argument (parameters_of (^^foo)[1]));\n+ static_assert (has_default_argument (parameters_of (^^foo)[2]));\n+ return ^^foo;\n+ }\n+}\n+\n+static_assert (^^a == bar ());\n+static_assert (^^b == baz ());\n+static_assert (^^foo == qux ());\n+static_assert (!has_default_argument (parameters_of (^^foo)[0]));\n+static_assert (has_default_argument (parameters_of (^^foo)[1]));\n+static_assert (has_default_argument (parameters_of (^^foo)[2]));\n", "prefixes": [] }