aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2025-08-19 11:07:14 -0400
committerPatrick Palka <ppalka@redhat.com>2025-08-19 11:07:14 -0400
commit0ab1e31807a19d699c462937ca639718360eac0c (patch)
treed6d6a51ac26bf5d2ac8bca8f193e6067fa2b56dd /gcc
parentf647d4f58a968079c342a0a3f7e71444d3836614 (diff)
downloadgcc-0ab1e31807a19d699c462937ca639718360eac0c.zip
gcc-0ab1e31807a19d699c462937ca639718360eac0c.tar.gz
gcc-0ab1e31807a19d699c462937ca639718360eac0c.tar.bz2
c++: constrained corresponding using from partial spec [PR121351]
When comparing constraints during correspondence checking for a using from a partial specialization, we need to substitute the partial specialization arguments into the constraints rather than the primary template arguments. Otherwise we incorrectly reject e.g. the below testcase as ambiguous since we substitute T=int* instead of T=int into #1's constraints and don't notice the correspondence. This patch corrects the recent r16-2771-gb9f1cc4e119da9 fix by using outer_template_args instead of TI_ARGS of the DECL_CONTEXT, which should always give the correct outer arguments for substitution. PR c++/121351 gcc/cp/ChangeLog: * class.cc (add_method): Use outer_template_args when substituting outer template arguments into constraints. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-using7.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/class.cc8
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-using7.C23
2 files changed, 27 insertions, 4 deletions
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 14acb9c..cf58f65 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -1365,14 +1365,14 @@ add_method (tree type, tree method, bool via_using)
{
if (TREE_CODE (fn) == TEMPLATE_DECL)
++processing_template_decl;
- if (tree ti = CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (fn)))
+ if (tree outer_args = outer_template_args (fn))
fn_constraints = tsubst_constraint_info (fn_constraints,
- TI_ARGS (ti),
+ outer_args,
tf_warning_or_error,
fn);
- if (tree ti = CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (method)))
+ if (tree outer_args = outer_template_args (method))
method_constraints = tsubst_constraint_info (method_constraints,
- TI_ARGS (ti),
+ outer_args,
tf_warning_or_error,
method);
if (TREE_CODE (fn) == TEMPLATE_DECL)
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-using7.C b/gcc/testsuite/g++.dg/cpp2a/concepts-using7.C
new file mode 100644
index 0000000..6e2c051
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-using7.C
@@ -0,0 +1,23 @@
+// PR c++/121351
+// { dg-do compile { target c++20 } }
+
+template<class T> concept C = true;
+
+template<class T>
+struct A;
+
+template<class T>
+struct A<T*> {
+ template<class U> void f(U) requires C<T>; // #1
+};
+
+template<class T>
+struct B : A<T> {
+ using A<T>::f;
+ template<class U> void f(U) requires C<int>; // #2
+};
+
+int main() {
+ B<int*> b;
+ b.f(42); // OK, #2 corresponds to and therefore hides #1
+}