On 1/21/26 3:29 AM, Marek Polacek wrote:
On Tue, Jan 20, 2026 at 09:54:10AM +0800, Jason Merrill wrote:
On 1/20/26 6:02 AM, Marek Polacek wrote:
On Sat, Jan 17, 2026 at 04:31:09PM +0800, Jason Merrill wrote:
On 1/17/26 8:47 AM, Marek Polacek wrote:
I suppose this could/should wait till GCC 17.
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
-- >8 --
During Reflection review it came up that is_std_substitution
handles NAMESPACE_DECLs accidentally: it wants either a class or a
class template, but is looking at the type of any decl.
Are there testcases affected by this?
I added code to check if we now return false for something that we
used to return true for, and found nothing. I ran dg.exp and old-deja.exp.
Let's include such a checking_assert in the return false path.
Yeah, I'll sleep better if we make sure that this patch doesn't
change behavior. How about this?
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
OK.
-- >8 --
During Reflection review it came up that is_std_substitution
handles NAMESPACE_DECLs accidentally: it wants either a class or a
class template, but is looking at the type of any decl. With this
patch, we return false for any _DECL except TYPE_DECL and
DECL_CLASS_TEMPLATE_P, but let's verify that we now don't return false
for something that used to yield true.
gcc/cp/ChangeLog:
* mangle.cc (is_std_substitution): Return false for any _DECL except
TYPE_DECL and DECL_CLASS_TEMPLATE_P. Verify that we don't return false
for something that used to yield true. Use NULL_TREE instead of NULL.
---
gcc/cp/mangle.cc | 52 +++++++++++++++++++++++++++++-------------------
1 file changed, 32 insertions(+), 20 deletions(-)
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index 06bd396c03e..4e1de212824 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -478,7 +478,7 @@ add_substitution (tree node)
}
/* Helper function for find_substitution. Returns nonzero if NODE,
- which may be a decl or a CLASS_TYPE, is a template-id with template
+ which may be a class or a class template, is a template-id with template
name of substitution_index[INDEX] in the ::std namespace, with
global module attachment. */
@@ -486,10 +486,28 @@ static bool
is_std_substitution (const tree node,
const substitution_identifier_index_t index)
{
- tree type = NULL;
- tree decl = NULL;
+ tree type = NULL_TREE;
+ tree decl = NULL_TREE;
- if (DECL_P (node))
+ auto std_substitution_p = [&] (tree decl, tree type)
+ {
+ if (!DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)))
+ return false;
+
+ if (!(TYPE_LANG_SPECIFIC (type) && TYPE_TEMPLATE_INFO (type)))
+ return false;
+
+ tree tmpl = TYPE_TI_TEMPLATE (type);
+ if (DECL_NAME (tmpl) != subst_identifiers[index])
+ return false;
+
+ if (modules_p () && get_originating_module (tmpl, true) >= 0)
+ return false;
+
+ return true;
+ };
+
+ if (TREE_CODE (node) == TYPE_DECL || DECL_CLASS_TEMPLATE_P (node))
{
type = TREE_TYPE (node);
decl = node;
@@ -500,23 +518,17 @@ is_std_substitution (const tree node,
decl = TYPE_NAME (node);
}
else
- /* These are not the droids you're looking for. */
- return false;
-
- if (!DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)))
- return false;
-
- if (!(TYPE_LANG_SPECIFIC (type) && TYPE_TEMPLATE_INFO (type)))
- return false;
-
- tree tmpl = TYPE_TI_TEMPLATE (type);
- if (DECL_NAME (tmpl) != subst_identifiers[index])
- return false;
-
- if (modules_p () && get_originating_module (tmpl, true) >= 0)
- return false;
+ {
+ /* We used to accept all _DECL nodes in this function but now we
+ only accept classes or class templates. Verify that we don't
+ return false for something that used to yield true. */
+ gcc_checking_assert (!DECL_P (node)
+ || !std_substitution_p (node, TREE_TYPE (node)));
+ /* These are not the droids you're looking for. */
+ return false;
+ }
- return true;
+ return std_substitution_p (decl, type);
}
/* Return the ABI tags (the TREE_VALUE of the "abi_tag" attribute entry) for T,
base-commit: cb6ce927ae0c084e9cfb4d73f07fef505026ca64