Author: Richard Smith Date: 2023-03-30T17:00:16-07:00 New Revision: 3524a9f84a0a1a106aa649a775066ba4d9e8ae0d
URL: https://github.com/llvm/llvm-project/commit/3524a9f84a0a1a106aa649a775066ba4d9e8ae0d DIFF: https://github.com/llvm/llvm-project/commit/3524a9f84a0a1a106aa649a775066ba4d9e8ae0d.diff LOG: Retain constraints in the canonical form of an auto type. This is necessary in order for type equality checking, for example across redeclarations, to require constraints to match. This is also a prerequisite for including the constraints in manglings. In passing, fix a bug where TemplateArgument::Profile would produce the same profile for two structurally different template names, which caused this change to re-expose the crash previously addressed by D133072, which it turns out had not quite addressed all problematic cases. Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/AST/ASTContext.cpp clang/lib/AST/TemplateBase.cpp clang/lib/AST/Type.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index dc8daa605fac7..4640ecccb9ad4 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -289,6 +289,8 @@ Bug Fixes to C++ Support (`#50866 <https://github.com/llvm/llvm-project/issues/50866>`_) - Fix ordering of function templates by constraints when they have template template parameters with diff erent nested constraints. +- Fix type equivalence comparison between auto types to take constraints into + account. Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 841a0995238e5..612fcd4897c8f 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -5794,12 +5794,19 @@ QualType ASTContext::getAutoTypeInternal( if (!DeducedType.isNull()) { Canon = DeducedType.getCanonicalType(); } else if (TypeConstraintConcept) { - Canon = getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack, - nullptr, {}, true); - // Find the insert position again. - [[maybe_unused]] auto *Nothing = - AutoTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(!Nothing && "canonical type broken"); + bool AnyNonCanonArgs = false; + ConceptDecl *CanonicalConcept = TypeConstraintConcept->getCanonicalDecl(); + auto CanonicalConceptArgs = ::getCanonicalTemplateArguments( + *this, TypeConstraintArgs, AnyNonCanonArgs); + if (CanonicalConcept != TypeConstraintConcept || AnyNonCanonArgs) { + Canon = + getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack, + CanonicalConcept, CanonicalConceptArgs, true); + // Find the insert position again. + [[maybe_unused]] auto *Nothing = + AutoTypes.FindNodeOrInsertPos(ID, InsertPos); + assert(!Nothing && "canonical type broken"); + } } } diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index f3d74b27e3267..c21e9c861875b 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -329,7 +329,7 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, ID.AddInteger(TemplateArg.NumExpansions); LLVM_FALLTHROUGH; case Template: - getAsTemplateOrTemplatePattern().Profile(ID); + ID.AddPointer(TemplateArg.Name); break; case Integral: diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 464939427a770..276b5aa59f759 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -4590,8 +4590,14 @@ AutoType::AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, auto *ArgBuffer = const_cast<TemplateArgument *>(getTypeConstraintArguments().data()); for (const TemplateArgument &Arg : TypeConstraintArgs) { - addDependence( - toSyntacticDependence(toTypeDependence(Arg.getDependence()))); + // If we have a deduced type, our constraints never affect semantic + // dependence. Prior to deduction, however, our canonical type depends + // on the template arguments, so we are a dependent type if any of them + // is dependent. + TypeDependence ArgDependence = toTypeDependence(Arg.getDependence()); + if (!DeducedAsType.isNull()) + ArgDependence = toSyntacticDependence(ArgDependence); + addDependence(ArgDependence); new (ArgBuffer++) TemplateArgument(Arg); } diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 611ebc9859388..2f13505d8ed71 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -1613,7 +1613,9 @@ static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( llvm_unreachable("Type nodes handled above"); case Type::Auto: - // FIXME: Implement deduction in dependent case. + // FIXME: It's not clear whether we should deduce the template arguments + // of a constrained deduced type. For now we treat them as a non-deduced + // context. if (P->isDependentType()) return Sema::TDK_Success; [[fallthrough]]; diff --git a/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp b/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp index 557ea02001bb7..a8f2ed3af2905 100644 --- a/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp +++ b/clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp @@ -81,9 +81,9 @@ namespace PR48617 { template <typename...> concept C = true; template <typename...> class A {}; - template <typename... Ts> C<Ts...> auto e(A<Ts...>) { return 0; } - template auto e<>(A<>); - template auto e<int>(A<int>); + template <typename... Ts> C<Ts...> auto e(A<Ts...>) { return 0; } // expected-note 2{{failed template argument deduction}} + template auto e<>(A<>); // expected-error {{does not refer to a function template}} + template auto e<int>(A<int>); // expected-error {{does not refer to a function template}} template <typename... Ts> C<Ts...> auto d(A<Ts...>) { return 0; } template C<> auto d<>(A<>); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits