c++: implicit dummy object in requires clause [PR103198]
In the testcase below satisfaction misbehaves for f and g ultimately because find_template_parameters fails to notice that the constraint 'val.x' depends on the template parms of the class template. In contrast, satisfaction works just fine for h. The problem seems to come down to a difference in how any_template_parm_r handles 'this' vs a dummy object: it walks the TREE_TYPE of the former but not the latter, and this causes us to miss the tparm dependencies in f/g's constraints since in their case the implicit object parm through which we access 'val' is a dummy object. (For h, since we know it's a non-static member function when parsing its trailing constraints, the implicit object parm is 'this', not a dummy object.) This patch fixes this inconsistency by making any_template_parm_r walk into the TREE_TYPE of a dummy object, like it already does for 'this'. PR c++/103198 gcc/cp/ChangeLog: * pt.c (any_template_parm_r): Walk the TREE_TYPE of a dummy object. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-this1.C: New test.
This commit is contained in:
parent
483092d3d9
commit
09c24fe42f
@ -10766,6 +10766,11 @@ any_template_parm_r (tree t, void *data)
|
||||
WALK_SUBTREE (TREE_TYPE (t));
|
||||
break;
|
||||
|
||||
case CONVERT_EXPR:
|
||||
if (is_dummy_object (t))
|
||||
WALK_SUBTREE (TREE_TYPE (t));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
30
gcc/testsuite/g++.dg/cpp2a/concepts-this1.C
Normal file
30
gcc/testsuite/g++.dg/cpp2a/concepts-this1.C
Normal file
@ -0,0 +1,30 @@
|
||||
// PR c++/103198
|
||||
// { dg-do compile { target c++20 } }
|
||||
|
||||
template<class T, class = void>
|
||||
struct A {
|
||||
T val;
|
||||
|
||||
template<class U>
|
||||
requires requires { val.x; }
|
||||
void f(U);
|
||||
|
||||
static void g(int)
|
||||
requires requires { val.x; };
|
||||
|
||||
void h(int)
|
||||
requires requires { val.x; };
|
||||
};
|
||||
|
||||
struct B { int x; };
|
||||
struct C { };
|
||||
|
||||
int main() {
|
||||
A<B>().f(0);
|
||||
A<B>().g(0);
|
||||
A<B>().h(0);
|
||||
|
||||
A<C>().f(0); // { dg-error "no match" }
|
||||
A<C>().g(0); // { dg-error "no match" }
|
||||
A<C>().h(0); // { dg-error "no match" }
|
||||
}
|
Loading…
Reference in New Issue
Block a user