public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-8732] c++: unqualified member template in constraint [PR101247]
@ 2021-07-13 14:03 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2021-07-13 14:03 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:2902f2d8424cfa365fec49401fa066e2b6de9ca4

commit r11-8732-g2902f2d8424cfa365fec49401fa066e2b6de9ca4
Author: Patrick Palka <ppalka@redhat.com>
Date:   Fri Jul 2 13:54:57 2021 -0400

    c++: unqualified member template in constraint [PR101247]
    
    Here any_template_parm_r is failing to mark the template parameters
    implicitly used by the unqualified use of 'd' inside the constraint
    because the code to do so assumes each level of a template parameter
    list points to the corresponding primary template, but here the
    parameter level for A in the out-of-line definition of A::B does not
    (nor do the parameter levels for A and C in the definition of A::C),
    which causes us to overlook the sharing.
    
    So it seems we can't in general depend on the TREE_TYPE of a template
    parameter level being non-empty here.  This patch partially fixes this
    by rewriting the relevant part of any_template_parm_r to not depend on
    the TREE_TYPE of outer levels.  We still depend on the innermost level
    to point to the innermost primary template, so we still crash on the
    commented out line in the below testcase.
    
            PR c++/101247
    
    gcc/cp/ChangeLog:
    
            * pt.c (any_template_parm_r) <case TEMPLATE_DECL>: Rewrite to
            use common_enclosing_class and to not depend on the TREE_TYPE
            of outer levels pointing to the corresponding primary template.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/concepts-memtmpl4.C: New test.
    
    (cherry picked from commit e3528ce197f8886869f95e8a8f901861a319851c)

Diff:
---
 gcc/cp/pt.c                                    | 23 +++++----------------
 gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl4.C | 28 ++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index af06c61e4f4..cbad49dc478 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10733,24 +10733,11 @@ any_template_parm_r (tree t, void *data)
       {
 	/* If T is a member template that shares template parameters with
 	   ctx_parms, we need to mark all those parameters for mapping.  */
-	tree dparms = DECL_TEMPLATE_PARMS (t);
-	tree cparms = ftpi->ctx_parms;
-	while (TMPL_PARMS_DEPTH (dparms) > ftpi->max_depth)
-	  dparms = TREE_CHAIN (dparms);
-	while (TMPL_PARMS_DEPTH (cparms) > TMPL_PARMS_DEPTH (dparms))
-	  cparms = TREE_CHAIN (cparms);
-	while (dparms
-	       && (TREE_TYPE (TREE_VALUE (dparms))
-		   != TREE_TYPE (TREE_VALUE (cparms))))
-	  dparms = TREE_CHAIN (dparms),
-	    cparms = TREE_CHAIN (cparms);
-	if (dparms)
-	  {
-	    int ddepth = TMPL_PARMS_DEPTH (dparms);
-	    tree dargs = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (t)));
-	    for (int i = 0; i < ddepth; ++i)
-	      WALK_SUBTREE (TMPL_ARGS_LEVEL (dargs, i+1));
-	  }
+	if (tree ctmpl = TREE_TYPE (INNERMOST_TEMPLATE_PARMS (ftpi->ctx_parms)))
+	  if (tree com = common_enclosing_class (DECL_CONTEXT (t),
+						 DECL_CONTEXT (ctmpl)))
+	    if (tree ti = CLASSTYPE_TEMPLATE_INFO (com))
+	      WALK_SUBTREE (TI_ARGS (ti));
       }
       break;
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl4.C
new file mode 100644
index 00000000000..625149e5025
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-memtmpl4.C
@@ -0,0 +1,28 @@
+// PR c++/101247
+// { dg-do compile { target concepts } }
+// A variant of concepts-memtmpl3.C where f is defined outside A's definition.
+
+template <typename> struct A {
+  template <typename c> static constexpr bool d = true;
+  struct B;
+  template <typename> struct C;
+};
+
+template <typename a>
+struct A<a>::B {
+  template <typename c> static void f(c) requires d<c>;
+};
+
+template <typename a>
+template <typename b>
+struct A<a>::C {
+  template <typename c> static void f(c) requires d<c>;
+  static void g() requires d<b>;
+};
+
+int main()
+{
+  A<void>::B::f(0);
+  A<void>::C<int>::f(0);
+  // A<void>::C<int>::g();
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-07-13 14:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-13 14:03 [gcc r11-8732] c++: unqualified member template in constraint [PR101247] Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).