https://gcc.gnu.org/g:5f7d74b555e8febd8b3def1f8e51742200f289ed
commit r16-6958-g5f7d74b555e8febd8b3def1f8e51742200f289ed Author: Marek Polacek <[email protected]> Date: Fri Jan 16 14:13:16 2026 -0500 c++: tighten up is_std_substitution 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. Reviewed-by: Jason Merrill <[email protected]> Diff: --- 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 06bd396c03ef..4e1de2128242 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,
