https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/199617
>From 6e611c57f705e5a89f1e7f8e699d2a457675e48c Mon Sep 17 00:00:00 2001 From: Younan Zhang <[email protected]> Date: Tue, 26 May 2026 15:12:52 +0800 Subject: [PATCH] [Clang] Profile the NNS of UnresolvedUsingType correctly in concept hashing They were sometimes incorrect because the written type doesn't contain an NNS which contains template parameters we're interested in. --- clang/lib/Sema/SemaConcept.cpp | 10 +++ .../test/SemaTemplate/concepts-using-decl.cpp | 69 +++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index ea03c3f408986..66d1f4db29410 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -399,6 +399,16 @@ class HashParameterMapping : public RecursiveASTVisitor<HashParameterMapping> { return true; } + bool TraverseUnresolvedUsingType(UnresolvedUsingType *T, + bool TraverseQualifier) { + // Sometimes the written type doesn't contain a qualifier which contains + // necessary template arguments, whereas the declaration does. + if (NestedNameSpecifier NNS = T->getDecl()->getQualifier(); + TraverseQualifier && NNS) + return inherited::TraverseNestedNameSpecifier(NNS); + return true; + } + bool TraverseInjectedClassNameType(InjectedClassNameType *T, bool TraverseQualifier) { return TraverseTemplateArguments(T->getTemplateArgs(SemaRef.Context)); diff --git a/clang/test/SemaTemplate/concepts-using-decl.cpp b/clang/test/SemaTemplate/concepts-using-decl.cpp index 26bd0b60b691c..dfdab707e4814 100644 --- a/clang/test/SemaTemplate/concepts-using-decl.cpp +++ b/clang/test/SemaTemplate/concepts-using-decl.cpp @@ -197,3 +197,72 @@ struct child : base<int> { }; } + +namespace GH198663 { + +template <class T> +concept HasIsTransparent = requires { typename T::is_transparent; }; + +template <class K, class V, class Compare> +struct FlatMapBase { + using key_compare = Compare; +}; + +template <class K, class V, class Compare> +struct FlatMap : FlatMapBase<K, V, Compare> { + using Base = FlatMapBase<K, V, Compare>; + + using typename Base::key_compare; + + void at(const K&) {} + void at(const K&) const {} + template <class Other> + void at(const Other&) + requires HasIsTransparent<key_compare> + {} + template <class Other> + void at(const Other&) const + requires HasIsTransparent<key_compare> + {} +}; + +template <class T> +struct Transparent { + T t; +}; + +struct TransparentComparator { + using is_transparent = void; + + template <class T> + bool operator()(const T&, const Transparent<T>&) const; + + template <class T> + bool operator()(const Transparent<T>&, const T& t) const; + + template <class T> + bool operator()(const T&, const T&) const; +}; + +struct NonTransparentComparator { + template <class T> + bool operator()(const T&, const Transparent<T>&) const; + + template <class T> + bool operator()(const Transparent<T>&, const T&) const; + + template <class T> + bool operator()(const T&, const T&) const; +}; + +template <class M> +concept CanAt = requires(M m, Transparent<int> k) { m.at(k); }; + +using TransparentMap = FlatMap<int, double, TransparentComparator>; +using NonTransparentMap = FlatMap<int, double, NonTransparentComparator>; + +static_assert(CanAt<TransparentMap>); + +static_assert(!CanAt<NonTransparentMap>); + +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
