https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/149264
>From 728de4d995079208605879a0ec30e8f76fe5220c Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Thu, 17 Jul 2025 14:17:02 +0800 Subject: [PATCH 1/2] [Clang] Ensure correct parameters are in the scope for constraint equivalence checking This is another case where untransformed constraint expressions led to inconsistent transforms. We did fix some of those issues by looking at parent scopes, however the parent instantiation scope is not always available because we could also reach here after the parents get instantiated. --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaConcept.cpp | 5 ++++- .../test/SemaTemplate/concepts-using-decl.cpp | 21 +++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index fcd3887ec7a09..6f55d14fd0aa5 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -808,6 +808,7 @@ Bug Fixes in This Version nested scopes. (#GH147495) - Fixed a failed assertion with an operator call expression which comes from a macro expansion when performing analysis for nullability attributes. (#GH138371) +- Fixed a concept equivalent checking crash due to untransformed constraint expressions. (#GH146614) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 834417f8e15ac..fbb2b8e650630 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -923,8 +923,11 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction( std::optional<LocalInstantiationScope> ScopeForParameters; if (const NamedDecl *ND = DeclInfo.getDecl(); ND && ND->isFunctionOrFunctionTemplate()) { - ScopeForParameters.emplace(S, /*CombineWithOuterScope=*/true); + ScopeForParameters.emplace(S); const FunctionDecl *FD = ND->getAsFunction(); + if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate(); + Template && Template->getInstantiatedFromMemberTemplate()) + FD = Template->getInstantiatedFromMemberTemplate()->getTemplatedDecl(); for (auto *PVD : FD->parameters()) { if (!PVD->isParameterPack()) { ScopeForParameters->InstantiatedLocal(PVD, PVD); diff --git a/clang/test/SemaTemplate/concepts-using-decl.cpp b/clang/test/SemaTemplate/concepts-using-decl.cpp index fca69dea5c88f..41f7b6d2f8faa 100644 --- a/clang/test/SemaTemplate/concepts-using-decl.cpp +++ b/clang/test/SemaTemplate/concepts-using-decl.cpp @@ -176,3 +176,24 @@ void func() { f.foo<10, 10>(); // expected-error {{no matching member function for call to 'foo'}} } } // namespace heads_without_concepts. + +namespace GH146614 { + +template <typename T> +struct base { + template <typename A> + void foo(A x) + requires (requires{x;}) + {} +}; + + +struct child : base<int> { + using base<int>::foo; + template <typename A> + void foo(A x) + requires (false) + {} +}; + +} >From f777409dce7d80a59ab348c6582ce7533939f2c3 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Thu, 17 Jul 2025 15:08:23 +0800 Subject: [PATCH 2/2] Fix the original case - we have to look at the outer scope! --- clang/lib/Sema/SemaConcept.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index fbb2b8e650630..5205ca0bca6fa 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -923,12 +923,14 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction( std::optional<LocalInstantiationScope> ScopeForParameters; if (const NamedDecl *ND = DeclInfo.getDecl(); ND && ND->isFunctionOrFunctionTemplate()) { - ScopeForParameters.emplace(S); + ScopeForParameters.emplace(S, /*CombineWithOuterScope=*/true); const FunctionDecl *FD = ND->getAsFunction(); if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate(); Template && Template->getInstantiatedFromMemberTemplate()) FD = Template->getInstantiatedFromMemberTemplate()->getTemplatedDecl(); for (auto *PVD : FD->parameters()) { + if (ScopeForParameters->getInstantiationOfIfExists(PVD)) + continue; if (!PVD->isParameterPack()) { ScopeForParameters->InstantiatedLocal(PVD, PVD); continue; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits