From 358165ded3c45115ce587d56ef792a9e7c0214ea Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Mon, 2 Sep 2024 13:42:42 +0800 Subject: [Clang][Concepts] Correct the CurContext for friend declarations (#106890) `FindInstantiatedDecl()` relies on the `CurContext` to find the corresponding class template instantiation for a class template declaration. Previously, we pushed the semantic declaration context for constraint comparison, which is incorrect for constraints on friend declarations. In issue #78101, the semantic context of the friend is the TU, so we missed the implicit template specialization `Template` when looking for the instantiation of the primary template `Template` at the time of checking the member instantiation; instead, we mistakenly picked up the explicit specialization `Template`, hence the error. As a bonus, this also fixes a crash when diagnosing constraints. The DeclarationName is not necessarily an identifier, so it's incorrect to call `getName()` on e.g. overloaded operators. Since the DiagnosticBuilder has correctly handled Decl printing, we don't need to find the printable name ourselves. Fixes https://github.com/llvm/llvm-project/issues/78101 --- clang/lib/Sema/SemaConcept.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'clang/lib/Sema/SemaConcept.cpp') diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 86d6f30..6a1b325 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -1012,7 +1012,14 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction( // possible that e.g. constraints involving C> and C are // perceived identical. std::optional ContextScope; - if (auto *RD = dyn_cast(DeclInfo.getDeclContext())) { + const DeclContext *DC = [&] { + if (!DeclInfo.getDecl()) + return DeclInfo.getDeclContext(); + return DeclInfo.getDecl()->getFriendObjectKind() + ? DeclInfo.getLexicalDeclContext() + : DeclInfo.getDeclContext(); + }(); + if (auto *RD = dyn_cast(DC)) { ThisScope.emplace(S, const_cast(RD), Qualifiers()); ContextScope.emplace(S, const_cast(cast(RD)), /*NewThisContext=*/false); -- cgit v1.1