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?

-- >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
-- 
2.52.0

Reply via email to