{
/* 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;
--- /dev/null
+// 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();
+}