Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

When streaming in a nested template-template parameter as in the
attached testcase, we end up reaching the containing template-template
parameter in 'tpl_parms_fini'. We should not set the DECL_CONTEXT to
this (nested) template-template parameter, as it should already be the
struct that the outer template-template parameter is declared on.

        PR c++/98881

gcc/cp/ChangeLog:

        * module.cc (trees_out::tpl_parms_fini): Clarify logic purely
        for checking purposes. Don't consider a template template
        parameter as the owning template.
        (trees_in::tpl_parms_fini): Don't consider a template template
        parameter as the owning template.

gcc/testsuite/ChangeLog:

        * g++.dg/modules/tpl-tpl-parm-3_a.H: New test.
        * g++.dg/modules/tpl-tpl-parm-3_b.C: New test.

Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
---
 gcc/cp/module.cc                                | 17 ++++++++++++-----
 gcc/testsuite/g++.dg/modules/tpl-tpl-parm-3_a.H | 11 +++++++++++
 gcc/testsuite/g++.dg/modules/tpl-tpl-parm-3_b.C | 13 +++++++++++++
 3 files changed, 36 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/tpl-tpl-parm-3_a.H
 create mode 100644 gcc/testsuite/g++.dg/modules/tpl-tpl-parm-3_b.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 67f132d28d7..5663d01ed9c 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -10126,10 +10126,14 @@ trees_out::tpl_parms_fini (tree tmpl, unsigned 
tpl_levels)
          tree dflt = TREE_PURPOSE (parm);
          tree_node (dflt);
 
-         if (streaming_p ())
+         if (CHECKING_P && streaming_p ())
            {
+             /* Sanity check that the DECL_CONTEXT we'll infer when
+                streaming in is correct.  */
              tree decl = TREE_VALUE (parm);
-             if (TREE_CODE (decl) == TEMPLATE_DECL)
+             if (TREE_CODE (decl) == TEMPLATE_DECL
+                 /* A template template parm is not the owning template.  */
+                 && !DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))
                {
                  tree ctx = DECL_CONTEXT (decl);
                  tree inner = DECL_TEMPLATE_RESULT (decl);
@@ -10164,8 +10168,13 @@ trees_in::tpl_parms_fini (tree tmpl, unsigned 
tpl_levels)
            return false;
          TREE_PURPOSE (parm) = dflt;
 
+         /* Original template template parms have a context
+            of their owning template.  Reduced ones do not.
+            But if TMPL is itself a template template parm
+            then it cannot be the owning template.  */
          tree decl = TREE_VALUE (parm);
-         if (TREE_CODE (decl) == TEMPLATE_DECL)
+         if (TREE_CODE (decl) == TEMPLATE_DECL
+             && !DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))
            {
              tree inner = DECL_TEMPLATE_RESULT (decl);
              tree tpi = (TREE_CODE (inner) == TYPE_DECL
@@ -10173,8 +10182,6 @@ trees_in::tpl_parms_fini (tree tmpl, unsigned 
tpl_levels)
                          : DECL_INITIAL (inner));
              bool original = (TEMPLATE_PARM_LEVEL (tpi)
                               == TEMPLATE_PARM_ORIG_LEVEL (tpi));
-             /* Original template template parms have a context
-                of their owning template.  Reduced ones do not.  */
              if (original)
                DECL_CONTEXT (decl) = tmpl;
            }
diff --git a/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-3_a.H 
b/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-3_a.H
new file mode 100644
index 00000000000..21bbc054fa3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-3_a.H
@@ -0,0 +1,11 @@
+// PR c++/98881
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+template <typename P> struct X {};
+
+template<template <typename> typename TT>
+struct X<TT<int>> {
+  template<template <typename> typename UU>
+  void f (X<UU<int>>&);
+};
diff --git a/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-3_b.C 
b/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-3_b.C
new file mode 100644
index 00000000000..234e822faa9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tpl-tpl-parm-3_b.C
@@ -0,0 +1,13 @@
+// PR c++/98881
+// { dg-additional-options "-fmodules-ts" }
+
+import "tpl-tpl-parm-3_a.H";
+
+template <typename T> struct Y {};
+template <typename T> struct Z {};
+
+void foo() {
+  X<Y<int>> y;
+  X<Z<int>> z;
+  y.f(z);
+}
-- 
2.43.2

Reply via email to