[PATCH] D136440: [clang] Do not hide base member using-decls with different template head.

Ilya Biryukov via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 27 01:53:31 PDT 2022


ilya-biryukov accepted this revision.
ilya-biryukov added inline comments.
This revision is now accepted and ready to land.


================
Comment at: clang/test/SemaTemplate/concepts-using-decl.cpp:174
+} // namespace heads_without_concepts.
\ No newline at end of file

----------------
NIT: add newline?


================
Comment at: clang/test/SemaTemplate/concepts-using-decl.cpp:112
+  expect<1>(baz{}.foo<Empty>()); // expected-error {{call to member function 'foo' is ambiguous}}
+}
+}
----------------
usaxena95 wrote:
> ilya-biryukov wrote:
> > Could you also check that `requires` clauses and constraints in template parameters do not hide each other?
> > ```
> > template <IsEmpty T> ...
> > // vs
> > template <class T> requires IsEmpty<T> ...
> > // vs
> > template <class T> void foo() requires IsEmpty<T> ...
> > ```
> > Should not hide each other.
> > 
> > Another interesting case (that probably does not yet work):
> > ```
> > struct base { template <class T> void foo(); };
> > struct derived : base { 
> >   using base::foo; 
> >   template <IsEmpty T> void foo();
> > };
> > ```
> > ^^ `derived().foo<Empty>()` will probably produce an ambiguity now (as we don't have an explicit requires clause here). I don't think it's worth fixing now, but keeping a test for it with a FIXME seems reasonable.
> The last test case would work though since we perform template head check if any template head is contrained. This is not ambiguous as overloading chooses the "most contrained" version.
Ah, right, this case is not ambiguous to start with. I think I made a mistake in the description.
The call with `Empty` would work either way and does not check anything: 
- we only see a constrained overload => it works,
- we see both overloads, but the one with `IsEmpty` is more specialized => it works.

I suggest also checking that `derived().foo<int>()` works. In that case the outcomes are different:
- we only see a constrained overload => compiler error,
- we see both overloads => constrained version does not match and the overload succeeds.

PS I was definitely under the impression that we are checking for the requires clause, but not constrained template parameters. However, I now see that I was wrong and we should also be fine with that case.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D136440/new/

https://reviews.llvm.org/D136440



More information about the cfe-commits mailing list