ChuanqiXu created this revision. ChuanqiXu added reviewers: rsmith, vsapsai, ilya-biryukov. ChuanqiXu added a project: clang-modules. Herald added a project: All. ChuanqiXu requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The current implementation to judge the similarity of TypeConstraint in ASTContext::isSameTemplateParameter is problematic, it couldn't handle the following case: C++ template <__integer_like _Tp, C<_Tp> Sentinel> constexpr _Tp operator()(_Tp &&__t, Sentinel &&last) const { return __t; } When we see 2 such declarations from different modules, we would judge their similarity by `ASTContext::isSame*` methods. But problems come for the TypeConstraint. Originally, we would profile each argument one by one. But it is not right. Since the profiling result of `_Tp` would refer to two different template type declarations. So it would get different results. It is right since the `_Tp` in different modules refers to different declarations indeed. So the same declaration in different modules would meet incorrect our-checking results. It is not the thing we want. We want to know if the TypeConstraint have the same expression. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D129068 Files: clang/lib/AST/ASTContext.cpp clang/test/Modules/concept.cppm Index: clang/test/Modules/concept.cppm =================================================================== --- clang/test/Modules/concept.cppm +++ clang/test/Modules/concept.cppm @@ -18,6 +18,9 @@ template <class _Tp> concept __member_size = requires(_Tp &&t) { t.size(); }; +template <class First, class Second> +concept C = requires(First x, Second y) { x+y; }; + struct A { public: template <Range T> @@ -29,6 +32,11 @@ constexpr __integer_like auto operator()(_Tp&& __t) const { return __t.size(); } + + template <__integer_like _Tp, C<_Tp> Sentinel> + constexpr _Tp operator()(_Tp &&__t, Sentinel &&last) const { + return __t; + } }; #endif @@ -51,4 +59,5 @@ auto operator+(S s) { return 0; } }; __fn{}(S()); + __fn{}(S(), S()); } Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -6245,11 +6245,14 @@ auto *TYTCArgs = TYTC->getTemplateArgsAsWritten(); if (TXTCArgs->NumTemplateArgs != TYTCArgs->NumTemplateArgs) return false; + llvm::FoldingSetNodeID XID, YID; - for (auto &ArgLoc : TXTCArgs->arguments()) - ArgLoc.getArgument().Profile(XID, X->getASTContext()); - for (auto &ArgLoc : TYTCArgs->arguments()) - ArgLoc.getArgument().Profile(YID, Y->getASTContext()); + auto *XConstraint = TXTC->getImmediatelyDeclaredConstraint(); + auto *YConstraint = TYTC->getImmediatelyDeclaredConstraint(); + if (XConstraint) + XConstraint->Profile(XID, *this, /*Canonical=*/true); + if (YConstraint) + YConstraint->Profile(YID, *this, /*Canonical=*/true); if (XID != YID) return false; } @@ -6524,10 +6527,10 @@ // and patterns match. if (const auto *TemplateX = dyn_cast<TemplateDecl>(X)) { const auto *TemplateY = cast<TemplateDecl>(Y); - return isSameEntity(TemplateX->getTemplatedDecl(), - TemplateY->getTemplatedDecl()) && - isSameTemplateParameterList(TemplateX->getTemplateParameters(), - TemplateY->getTemplateParameters()); + return isSameEntity(TemplateX->getTemplatedDecl(), + TemplateY->getTemplatedDecl()) && + isSameTemplateParameterList(TemplateX->getTemplateParameters(), + TemplateY->getTemplateParameters()); } // Fields with the same name and the same type match.
Index: clang/test/Modules/concept.cppm =================================================================== --- clang/test/Modules/concept.cppm +++ clang/test/Modules/concept.cppm @@ -18,6 +18,9 @@ template <class _Tp> concept __member_size = requires(_Tp &&t) { t.size(); }; +template <class First, class Second> +concept C = requires(First x, Second y) { x+y; }; + struct A { public: template <Range T> @@ -29,6 +32,11 @@ constexpr __integer_like auto operator()(_Tp&& __t) const { return __t.size(); } + + template <__integer_like _Tp, C<_Tp> Sentinel> + constexpr _Tp operator()(_Tp &&__t, Sentinel &&last) const { + return __t; + } }; #endif @@ -51,4 +59,5 @@ auto operator+(S s) { return 0; } }; __fn{}(S()); + __fn{}(S(), S()); } Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -6245,11 +6245,14 @@ auto *TYTCArgs = TYTC->getTemplateArgsAsWritten(); if (TXTCArgs->NumTemplateArgs != TYTCArgs->NumTemplateArgs) return false; + llvm::FoldingSetNodeID XID, YID; - for (auto &ArgLoc : TXTCArgs->arguments()) - ArgLoc.getArgument().Profile(XID, X->getASTContext()); - for (auto &ArgLoc : TYTCArgs->arguments()) - ArgLoc.getArgument().Profile(YID, Y->getASTContext()); + auto *XConstraint = TXTC->getImmediatelyDeclaredConstraint(); + auto *YConstraint = TYTC->getImmediatelyDeclaredConstraint(); + if (XConstraint) + XConstraint->Profile(XID, *this, /*Canonical=*/true); + if (YConstraint) + YConstraint->Profile(YID, *this, /*Canonical=*/true); if (XID != YID) return false; } @@ -6524,10 +6527,10 @@ // and patterns match. if (const auto *TemplateX = dyn_cast<TemplateDecl>(X)) { const auto *TemplateY = cast<TemplateDecl>(Y); - return isSameEntity(TemplateX->getTemplatedDecl(), - TemplateY->getTemplatedDecl()) && - isSameTemplateParameterList(TemplateX->getTemplateParameters(), - TemplateY->getTemplateParameters()); + return isSameEntity(TemplateX->getTemplatedDecl(), + TemplateY->getTemplatedDecl()) && + isSameTemplateParameterList(TemplateX->getTemplateParameters(), + TemplateY->getTemplateParameters()); } // Fields with the same name and the same type match.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits