Author: Erich Keane Date: 2022-11-16T07:33:15-08:00 New Revision: 6c38ffc7b6f46fda94e29ed6cf34b814aeeaab45
URL: https://github.com/llvm/llvm-project/commit/6c38ffc7b6f46fda94e29ed6cf34b814aeeaab45 DIFF: https://github.com/llvm/llvm-project/commit/6c38ffc7b6f46fda94e29ed6cf34b814aeeaab45.diff LOG: [Concepts] Fix friend-checking to include NTTPs More work for temp.friend p9, this fixes a previous bug where we didn't properly consider a friend to depend on the enclosing template if it only did so via an NTTP. Added: Modified: clang/lib/Sema/SemaTemplate.cpp clang/test/SemaTemplate/concepts-friends.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index b04458687ac02..08ff4f4aecb5e 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1707,6 +1707,18 @@ class ConstraintRefersToContainingTemplateChecker Result = true; } + void CheckNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { + assert(D->getDepth() <= TemplateDepth && + "Nothing should reference a value below the actual template depth, " + "depth is likely wrong"); + if (D->getDepth() != TemplateDepth) + Result = true; + + // Necessary because the type of the NTTP might be what refers to the parent + // constriant. + TransformType(D->getType()); + } + public: using inherited = TreeTransform<ConstraintRefersToContainingTemplateChecker>; @@ -1742,6 +1754,8 @@ class ConstraintRefersToContainingTemplateChecker // unreachable should catch future instances/cases. if (auto *TD = dyn_cast<TypedefNameDecl>(D)) TransformType(TD->getUnderlyingType()); + else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(D)) + CheckNonTypeTemplateParmDecl(NTTPD); else if (auto *VD = dyn_cast<ValueDecl>(D)) TransformType(VD->getType()); else if (auto *TD = dyn_cast<TemplateDecl>(D)) diff --git a/clang/test/SemaTemplate/concepts-friends.cpp b/clang/test/SemaTemplate/concepts-friends.cpp index 6aa461841f9ca..3a9b308a65c5d 100644 --- a/clang/test/SemaTemplate/concepts-friends.cpp +++ b/clang/test/SemaTemplate/concepts-friends.cpp @@ -411,3 +411,33 @@ namespace RefersToParentInConstraint { S<long> y; } } // namespace RefersToParentInConstraint + +namespace NTTP { + struct Base{}; + template<int N> + struct S : Base { + // N is from the parent template. + template<typename T> + friend int templ_func(Base&) requires(N > 0) + { return 10; } + }; + + template<typename T> + struct U : Base { + template<T N> + friend int templ_func(Base&) requires(N>0) + { return 10; } + }; + + void use() { + S<1> s1; + templ_func<float>(s1); + S<2> s2; + templ_func<float>(s2); + + U<int> u1; + templ_func<1>(u1); + U<short> u2; + templ_func<1>(u2); + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits