[clang] 122b938 - [Clang][Sema] Substitute constraints only for declarations with different lexical contexts

Alexander Shaposhnikov via cfe-commits cfe-commits at lists.llvm.org
Wed May 17 14:36:46 PDT 2023


Author: Alexander Shaposhnikov
Date: 2023-05-17T21:24:44Z
New Revision: 122b938944ceb966e04d7a4d253f7f9ba27c477d

URL: https://github.com/llvm/llvm-project/commit/122b938944ceb966e04d7a4d253f7f9ba27c477d
DIFF: https://github.com/llvm/llvm-project/commit/122b938944ceb966e04d7a4d253f7f9ba27c477d.diff

LOG: [Clang][Sema] Substitute constraints only for declarations with different lexical contexts

Substitute constraints only for declarations with different lexical contexts.
This results in avoiding the substitution of constraints during the redeclaration check
inside a class (and by product caching the wrong substitution result).

Test plan: ninja check-all

Differential revision: https://reviews.llvm.org/D150730

Added: 
    clang/test/SemaTemplate/concepts-no-early-substitution.cpp

Modified: 
    clang/lib/Sema/SemaConcept.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 1126c2c517fe4..2f5fb8f8d029e 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -780,7 +780,9 @@ bool Sema::AreConstraintExpressionsEqual(const NamedDecl *Old,
                                          const Expr *NewConstr) {
   if (OldConstr == NewConstr)
     return true;
-  if (Old && New && Old != New) {
+  // C++ [temp.constr.decl]p4
+  if (Old && New && Old != New &&
+      Old->getLexicalDeclContext() != New->getLexicalDeclContext()) {
     if (const Expr *SubstConstr =
             SubstituteConstraintExpression(*this, Old, OldConstr))
       OldConstr = SubstConstr;

diff  --git a/clang/test/SemaTemplate/concepts-no-early-substitution.cpp b/clang/test/SemaTemplate/concepts-no-early-substitution.cpp
new file mode 100644
index 0000000000000..9e576f16a263b
--- /dev/null
+++ b/clang/test/SemaTemplate/concepts-no-early-substitution.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=c++20 -x c++ %s -verify -fsyntax-only
+// expected-no-diagnostics
+
+template <typename T0>
+concept HasMemberBegin = requires(T0 t) { t.begin(); };
+
+struct GetBegin {
+  template <HasMemberBegin T1>
+  void operator()(T1);
+};
+
+GetBegin begin;
+
+template <typename T2>
+concept Concept = requires(T2 t) { begin(t); };
+
+struct Subrange;
+
+template <typename T3>
+struct View {
+  Subrange &getSubrange();
+
+  operator bool()
+    requires true;
+
+  operator bool()
+    requires requires { begin(getSubrange()); };
+
+  void begin();
+};
+
+struct Subrange : View<void> {};
+static_assert(Concept<Subrange>);


        


More information about the cfe-commits mailing list