ychen updated this revision to Diff 464731. ychen added a comment. - address @erichkeane's comment.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D135088/new/ https://reviews.llvm.org/D135088 Files: clang/lib/AST/ASTContext.cpp clang/lib/AST/DeclTemplate.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaTemplate.cpp clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
Index: clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp =================================================================== --- clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp +++ clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp @@ -82,18 +82,12 @@ template <typename...> class A {}; template <typename... Ts> C<Ts...> auto e(A<Ts...>) { return 0; } - - // FIXME: The error here does not make sense. template auto e<>(A<>); - // expected-error@-1 {{explicit instantiation of 'e' does not refer to a function template}} - // expected-note@-5 {{candidate template ignored: failed template argument deduction}} - - // FIXME: Should be able to instantiate this with no errors. - template C<int> auto e<int>(A<int>); - // expected-error@-1 {{explicit instantiation of 'e' does not refer to a function template}} - // expected-note@-10 {{candidate template ignored: could not match 'C<int, Ts...> auto' against 'C<int> auto'}} - - template C<> auto e<>(A<>); + template auto e<int>(A<int>); + + template <typename... Ts> C<Ts...> auto d(A<Ts...>) { return 0; } + template C<> auto d<>(A<>); + template C<int> auto d<int>(A<int>); template <typename... Ts> A<Ts...> c(Ts...); int f = e(c(1, 2)); Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -7933,12 +7933,26 @@ : Kind), TemplateArgLoc)) return false; - } else if (Kind != Sema::TPL_TemplateTemplateArgumentMatch) { + } + + if (Kind != Sema::TPL_TemplateTemplateArgumentMatch && + !isa<TemplateTemplateParmDecl>(Old)) { const Expr *NewC = nullptr, *OldC = nullptr; - if (const auto *TC = cast<TemplateTypeParmDecl>(New)->getTypeConstraint()) - NewC = TC->getImmediatelyDeclaredConstraint(); - if (const auto *TC = cast<TemplateTypeParmDecl>(Old)->getTypeConstraint()) - OldC = TC->getImmediatelyDeclaredConstraint(); + + if (isa<TemplateTypeParmDecl>(New)) { + if (const auto *TC = cast<TemplateTypeParmDecl>(New)->getTypeConstraint()) + NewC = TC->getImmediatelyDeclaredConstraint(); + if (const auto *TC = cast<TemplateTypeParmDecl>(Old)->getTypeConstraint()) + OldC = TC->getImmediatelyDeclaredConstraint(); + } else if (isa<NonTypeTemplateParmDecl>(New)) { + if (const Expr *E = cast<NonTypeTemplateParmDecl>(New) + ->getPlaceholderTypeConstraint()) + NewC = E; + if (const Expr *E = cast<NonTypeTemplateParmDecl>(Old) + ->getPlaceholderTypeConstraint()) + OldC = E; + } else + llvm_unreachable("unexpected template parameter type"); auto Diagnose = [&] { S.Diag(NewC ? NewC->getBeginLoc() : New->getBeginLoc(), Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -8661,10 +8661,11 @@ // C++2a [class.spaceship]p2 [P2002R0]: // Let R be the declared return type [...]. If R is auto, [...]. Otherwise, // R shall not contain a placeholder type. - if (DCK == DefaultedComparisonKind::ThreeWay && - FD->getDeclaredReturnType()->getContainedDeducedType() && - !Context.hasSameType(FD->getDeclaredReturnType(), - Context.getAutoDeductType())) { + if (QualType RT = FD->getDeclaredReturnType(); + DCK == DefaultedComparisonKind::ThreeWay && + RT->getContainedDeducedType() && + (!Context.hasSameType(RT, Context.getAutoDeductType()) || + RT->getContainedAutoType()->isConstrained())) { Diag(FD->getLocation(), diag::err_defaulted_comparison_deduced_return_type_not_auto) << (int)DCK << FD->getDeclaredReturnType() << Context.AutoDeductTy Index: clang/lib/AST/DeclTemplate.cpp =================================================================== --- clang/lib/AST/DeclTemplate.cpp +++ clang/lib/AST/DeclTemplate.cpp @@ -529,6 +529,9 @@ ID.AddInteger(0); ID.AddBoolean(NTTP->isParameterPack()); NTTP->getType().getCanonicalType().Profile(ID); + ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint()); + if (const Expr *E = NTTP->getPlaceholderTypeConstraint()) + E->Profile(ID, C, /*Canonical=*/true); continue; } if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) { Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -696,7 +696,11 @@ if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) { ID.AddInteger(1); ID.AddBoolean(NTTP->isParameterPack()); + const Expr *TC = NTTP->getPlaceholderTypeConstraint(); + ID.AddBoolean(TC != nullptr); ID.AddPointer(NTTP->getType().getCanonicalType().getAsOpaquePtr()); + if (TC) + TC->Profile(ID, C, /*Canonical=*/true); if (NTTP->isExpandedParameterPack()) { ID.AddBoolean(true); ID.AddInteger(NTTP->getNumExpansionTypes()); @@ -5737,12 +5741,9 @@ QualType Canon; if (!IsCanon) { if (DeducedType.isNull()) { - SmallVector<TemplateArgument, 4> CanonArgs; - bool AnyNonCanonArgs = - ::getCanonicalTemplateArguments(*this, TypeConstraintArgs, CanonArgs); - if (AnyNonCanonArgs) { - Canon = getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack, - TypeConstraintConcept, CanonArgs, true); + if (TypeConstraintConcept) { + Canon = getAutoTypeInternal(QualType(), Keyword, false, IsPack, nullptr, + {}, true); // Find the insert position again. [[maybe_unused]] auto *Nothing = AutoTypes.FindNodeOrInsertPos(ID, InsertPos); @@ -6305,7 +6306,11 @@ if (auto *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) { auto *TY = cast<NonTypeTemplateParmDecl>(Y); return TX->isParameterPack() == TY->isParameterPack() && - TX->getASTContext().hasSameType(TX->getType(), TY->getType()); + TX->getASTContext().hasSameType(TX->getType(), TY->getType()) && + TX->hasPlaceholderTypeConstraint() == + TY->hasPlaceholderTypeConstraint() && + isSameConstraintExpr(TX->getPlaceholderTypeConstraint(), + TY->getPlaceholderTypeConstraint()); } auto *TX = cast<TemplateTemplateParmDecl>(X);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits