Skip to content

[Clang] Profile the NNS of UnresolvedUsingType and CXXThisType correctly in concept hashing#199617

Merged
zyn0217 merged 1 commit into
llvm:mainfrom
zyn0217:198663
Jun 1, 2026
Merged

[Clang] Profile the NNS of UnresolvedUsingType and CXXThisType correctly in concept hashing#199617
zyn0217 merged 1 commit into
llvm:mainfrom
zyn0217:198663

Conversation

@zyn0217
Copy link
Copy Markdown
Contributor

@zyn0217 zyn0217 commented May 26, 2026

They were sometimes incorrect because the written type doesn't contain an NNS which contains template parameters we're interested in.

No release note because the bug broke MS STL and I want to backport it to the last 22.x release

Fixes #198663

@zyn0217 zyn0217 requested a review from cor3ntin May 26, 2026 07:20
@llvmorg-github-actions llvmorg-github-actions Bot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels May 26, 2026
@llvmorg-github-actions
Copy link
Copy Markdown

@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)

Changes

They were sometimes incorrect because the written type doesn't contain an NNS which contains template parameters we're interested in.

No release note because the bug broke MS STL and I want to backport it to the last 22.x release

Fixes #198663


Full diff: https://github.com/llvm/llvm-project/pull/199617.diff

2 Files Affected:

  • (modified) clang/lib/Sema/SemaConcept.cpp (+10)
  • (modified) clang/test/SemaTemplate/concepts-using-decl.cpp (+69)
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>);
+
+}

@zyn0217
Copy link
Copy Markdown
Contributor Author

zyn0217 commented May 26, 2026

@StephanTLavavej in case you're able to help us test this patch over STL tests, thanks!

Comment thread clang/lib/Sema/SemaConcept.cpp Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 26, 2026

🐧 Linux x64 Test Results

  • 118173 tests passed
  • 4798 tests skipped

✅ The build succeeded and all tests passed.

@zyn0217
Copy link
Copy Markdown
Contributor Author

zyn0217 commented May 26, 2026

The test failure seems unrelated

@StephanTLavavej
Copy link
Copy Markdown
Member

Thank you - unfortunately I'm not set up to build Clang locally and don't have the time to learn how.

@shafik
Copy link
Copy Markdown
Contributor

shafik commented May 27, 2026

CC @gracicot in case you want to verify it fixes it for you as well.

@gracicot
Copy link
Copy Markdown

Hmm. This does not seem to fix the problem for me. I built clang from the 198663 branch and I still observe the issue on my local machine.

I pushed this commit in my repo that reproduce the issue: gracicot/kangaru@04eb61d - depends on fmt and catch2 for building.

I was not able to create a minimal repro sadly.

@zyn0217
Copy link
Copy Markdown
Contributor Author

zyn0217 commented May 28, 2026

@gracicot Can you please provide us with a self contained reproducer? It would be nice if we don't have to spend time setting up a build environment, thanks!

@gracicot
Copy link
Copy Markdown

gracicot commented May 29, 2026

@zyn0217 I took some time and was able to reduce it:

template<typename T>
auto mv(T& t) -> T&&;

template<typename S, typename T>
concept does_foo = requires(S s) {
	s.template foo<T>();
};

template<typename S>
struct type {
	S member;
	
	template<typename T>
	auto foo() -> T requires does_foo<decltype(mv(member)), T>;
};

struct returns_int {
	template<typename T>
	auto foo() -> T;
};

struct nothing {};

#ifdef REPRO
static_assert(does_foo<type<returns_int>&, int>);
#endif

static_assert(not does_foo<type<nothing>&, int>);

With -DREPRO, it passes with clang 21, but fails with clang 22 and commit 426143d11ec8 of zyn0217/198663.

The key thing I found is that it's specific to a concept checking for a template function, and that function has to return decltype of an expression that involves a function and a non static data member.

…ashing

They were sometimes incorrect because the written type doesn't contain an
NNS which contains template parameters we're interested in.
@zyn0217 zyn0217 changed the title [Clang] Profile the NNS of UnresolvedUsingType correctly in concept hashing [Clang] Profile the NNS of UnresolvedUsingType and CXXThisType correctly in concept hashing Jun 1, 2026
@zyn0217
Copy link
Copy Markdown
Contributor Author

zyn0217 commented Jun 1, 2026

@gracicot The latest commit should fix that issue, thanks for the feedback!

@zyn0217 zyn0217 requested a review from cor3ntin June 1, 2026 11:01
Copy link
Copy Markdown
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@zyn0217 zyn0217 merged commit 06ffb65 into llvm:main Jun 1, 2026
10 checks passed
@zyn0217 zyn0217 added this to the LLVM 22.x Release milestone Jun 2, 2026
@github-project-automation github-project-automation Bot moved this from Needs Triage to Done in LLVM Release Status Jun 2, 2026
@github-project-automation github-project-automation Bot moved this to Needs Triage in LLVM Release Status Jun 2, 2026
@zyn0217
Copy link
Copy Markdown
Contributor Author

zyn0217 commented Jun 2, 2026

/cherry-pick 06ffb65

@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Jun 2, 2026

/pull-request #200988

dyung pushed a commit to llvmbot/llvm-project that referenced this pull request Jun 2, 2026
…tly in concept hashing (llvm#199617)

They were sometimes incorrect because the written type doesn't contain
an NNS which contains template parameters we're interested in.

No release note because the bug broke MS STL and I want to backport it
to the last 22.x release

Fixes llvm#198663

(cherry picked from commit 06ffb65)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

Development

Successfully merging this pull request may close these issues.

[Clang] Compiler regression affecting concept-constrained flat_map::at()

6 participants