[all-commits] [llvm/llvm-project] 56099d: [clang] Do not hide base member using-decls with d...

Utkarsh Saxena via All-commits all-commits at lists.llvm.org
Thu Oct 27 02:53:04 PDT 2022


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 56099d242809f80984e4afa37693177484aab13d
      https://github.com/llvm/llvm-project/commit/56099d242809f80984e4afa37693177484aab13d
  Author: Utkarsh Saxena <usx at google.com>
  Date:   2022-10-27 (Thu, 27 Oct 2022)

  Changed paths:
    M clang/docs/ReleaseNotes.rst
    M clang/include/clang/Sema/Sema.h
    M clang/lib/Sema/SemaOverload.cpp
    A clang/test/SemaTemplate/concepts-using-decl.cpp

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

Fixes: https://github.com/llvm/llvm-project/issues/50886

**Adding requires clause to template head** or **constraining the template parameter type** is ineffective because, even though it creates a non-equivalent template head [temp.over.link#6](https://eel.is/c++draft/temp.over.link#6) and hence eligible for overload resolution, `Derived::foo` still [hides any previous using decl](https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaOverload.cpp#L1283-L1301,).
Clang diverges from gcc here and can be seen more clearly in this example:
```
struct base {
  template <int N, int M>
  int foo() { return 1; };
};

struct bar : public base {
  using base::foo;
  template <int N>
  int foo() { return 2; };
};

int main() {
  bar f;
  f.foo<10, 10>(); // clang previously errored while GCC does not.
}
```
https://godbolt.org/z/v5hnh6czq. We see that `bar::foo` hides `base::foo` because it only differs in the head.

Adding a trailing `requires` to the definition was a nice find. In this case, clang considers them [overloads](https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaOverload.cpp#L1148-L1152) because of [mismatching requires clause.](https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaOverload.cpp#L1390-L1405). So both of them make it to the overload resolution (where constrained Derived::foo is rejected then).

---

In this patch, we do not ignore matching the template head (template parameters, type contraints and trailing requires) while considering whether the using decl of base member should be hidden. The return type of a templated function is still not considered as different return types would create ambiguous candidates.

The changed tests looks reasonable and also matches GCC behaviour: https://godbolt.org/z/8KqPEThrY

Note: We are now able to create an ambiguity in case where both base member and derived member specialisations satisfy the constraints (when the constraints are not same). Ideally using-decl should not create ambiguity. I plan to fix this later if it gathers more attention.

Reviewed By: ilya-biryukov, #clang-language-wg

Differential Revision: https://reviews.llvm.org/D136440




More information about the All-commits mailing list