[clang] [Clang] Consider outer instantiation scopes for constraint normalization (PR #114749)

Younan Zhang via cfe-commits cfe-commits at lists.llvm.org
Sun Nov 3 23:46:39 PST 2024


https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/114749

We need to compare constraint expressions when instantiating a friend declaration that is lexically defined within a class template. Since the evaluation is deferred, the expression might refer to untransformed function parameters such that the substitution needs the mapping of instantiation.

These mappings are maintained by the function declaration instantiation, so we need to establish a "transparent" LocalInstantiationScope before substituting into the constraint.

No release note as this fixes a regression in 19.

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

>From a218508f38ebfc2e0ff19d08317fd3a13c3e8d36 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Mon, 4 Nov 2024 15:30:01 +0800
Subject: [PATCH] [Clang] Consider outer instantiation scopes for constraint
 normalization

We need to compare constraint expressions when instantiating a friend
declaration that is lexically defined within a class template. Since the
evaluation is deferred, the expression might refer to untransformed function
parameters such that the substitution needs the mapping of instantiation.

These mappings are maintained by the function declaration instantiation,
so we need to establish a "transparent" LocalInstantiationScope before
substituting into the constraint.
---
 clang/lib/Sema/SemaConcept.cpp                   |  2 +-
 .../SemaTemplate/concepts-out-of-line-def.cpp    | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index e36ee062213716..bc988001ea7e46 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -975,7 +975,7 @@ 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();
     for (auto *PVD : FD->parameters()) {
       if (!PVD->isParameterPack()) {
diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
index fe8f74928fc370..dd518d283c83c8 100644
--- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -702,3 +702,19 @@ class TTP;
 C v;
 
 } // namespace GH93099
+
+namespace GH114685 {
+
+template <typename T> struct ptr {
+  template <typename U>
+  friend ptr<U> make_item(auto &&args)
+    requires(sizeof(args) > 1);
+};
+
+template <typename U>
+ptr<U> make_item(auto &&args)
+  requires(sizeof(args) > 1) {}
+
+ptr<char> p;
+
+} // namespace GH114685



More information about the cfe-commits mailing list