luken-google updated this revision to Diff 460756. luken-google added a comment.
Refactor to check during template overload evaluation Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D133052/new/ https://reviews.llvm.org/D133052 Files: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaInit.cpp clang/lib/Sema/SemaOverload.cpp clang/test/SemaTemplate/concepts.cpp Index: clang/test/SemaTemplate/concepts.cpp =================================================================== --- clang/test/SemaTemplate/concepts.cpp +++ clang/test/SemaTemplate/concepts.cpp @@ -262,3 +262,18 @@ template <class> struct S {}; void f(C<GH55567::S> auto); } // namespace GH55567 + +namespace Issue50891 { +template <typename T> +concept Numeric = + requires(T a) { + foo(a); + }; + +struct Deferred { + friend void foo(Deferred); + template <Numeric TO> operator TO(); +}; + +static_assert(Numeric<Deferred>); // should not crash clang +} // namespace Issue50891 Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -7565,6 +7565,24 @@ return; } + // We won't go through a user-defined type conversion function to convert a + // derived to base as such conversions are given Conversion Rank. They only + // go through a copy constructor. 13.3.3.1.2-p4 [over.ics.user] + // Peforming this check here avoids possible infinite template expansion + // in the following call to DeduceTemplateArguments(). + QualType FromCanon = + Context.getCanonicalType(From->getType().getUnqualifiedType()); + QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType(); + if (FromCanon == ToCanon || + IsDerivedFrom(CandidateSet.getLocation(), FromCanon, ToCanon)) { + OverloadCandidate &Candidate = CandidateSet.addCandidate(); + Candidate.FoundDecl = FoundDecl; + Candidate.Function = FunctionTemplate->getTemplatedDecl(); + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_trivial_conversion; + return; + } + TemplateDeductionInfo Info(CandidateSet.getLocation()); CXXConversionDecl *Specialization = nullptr; if (TemplateDeductionResult Result Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -4020,6 +4020,9 @@ // // Note: SecondStepOfCopyInit is only ever true in this case when // evaluating whether to produce a C++98 compatibility warning. + // + // The last check avoids an infinite template expansion loop in + // requirements checking by skipping the conversion functions check. if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 && !SecondStepOfCopyInit) { Expr *Initializer = Args[0]; Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -267,17 +267,17 @@ `GH55216 <https://github.com/llvm/llvm-project/issues/55216>`_. - Correctly set expression evaluation context as 'immediate function context' in consteval functions. - This fixes `GH51182 <https://github.com/llvm/llvm-project/issues/51182>`_. - + This fixes `GH51182 <https://github.com/llvm/llvm-project/issues/51182>` - Fixes an assert crash caused by looking up missing vtable information on ``consteval`` virtual functions. Fixes `GH55065 <https://github.com/llvm/llvm-project/issues/55065>`_. - - Skip rebuilding lambda expressions in arguments of immediate invocations. This fixes `GH56183 <https://github.com/llvm/llvm-project/issues/56183>`_, `GH51695 <https://github.com/llvm/llvm-project/issues/51695>`_, `GH50455 <https://github.com/llvm/llvm-project/issues/50455>`_, `GH54872 <https://github.com/llvm/llvm-project/issues/54872>`_, `GH54587 <https://github.com/llvm/llvm-project/issues/54587>`_. +- Fixed a crash during template instantiation on a conversion operator during constraint + evaulation. Fixes `GH50891 <https://github.com/llvm/llvm-project/issues/50891>`_. C++2b Feature Support ^^^^^^^^^^^^^^^^^^^^^
Index: clang/test/SemaTemplate/concepts.cpp =================================================================== --- clang/test/SemaTemplate/concepts.cpp +++ clang/test/SemaTemplate/concepts.cpp @@ -262,3 +262,18 @@ template <class> struct S {}; void f(C<GH55567::S> auto); } // namespace GH55567 + +namespace Issue50891 { +template <typename T> +concept Numeric = + requires(T a) { + foo(a); + }; + +struct Deferred { + friend void foo(Deferred); + template <Numeric TO> operator TO(); +}; + +static_assert(Numeric<Deferred>); // should not crash clang +} // namespace Issue50891 Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -7565,6 +7565,24 @@ return; } + // We won't go through a user-defined type conversion function to convert a + // derived to base as such conversions are given Conversion Rank. They only + // go through a copy constructor. 13.3.3.1.2-p4 [over.ics.user] + // Peforming this check here avoids possible infinite template expansion + // in the following call to DeduceTemplateArguments(). + QualType FromCanon = + Context.getCanonicalType(From->getType().getUnqualifiedType()); + QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType(); + if (FromCanon == ToCanon || + IsDerivedFrom(CandidateSet.getLocation(), FromCanon, ToCanon)) { + OverloadCandidate &Candidate = CandidateSet.addCandidate(); + Candidate.FoundDecl = FoundDecl; + Candidate.Function = FunctionTemplate->getTemplatedDecl(); + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_trivial_conversion; + return; + } + TemplateDeductionInfo Info(CandidateSet.getLocation()); CXXConversionDecl *Specialization = nullptr; if (TemplateDeductionResult Result Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -4020,6 +4020,9 @@ // // Note: SecondStepOfCopyInit is only ever true in this case when // evaluating whether to produce a C++98 compatibility warning. + // + // The last check avoids an infinite template expansion loop in + // requirements checking by skipping the conversion functions check. if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 && !SecondStepOfCopyInit) { Expr *Initializer = Args[0]; Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -267,17 +267,17 @@ `GH55216 <https://github.com/llvm/llvm-project/issues/55216>`_. - Correctly set expression evaluation context as 'immediate function context' in consteval functions. - This fixes `GH51182 <https://github.com/llvm/llvm-project/issues/51182>`_. - + This fixes `GH51182 <https://github.com/llvm/llvm-project/issues/51182>` - Fixes an assert crash caused by looking up missing vtable information on ``consteval`` virtual functions. Fixes `GH55065 <https://github.com/llvm/llvm-project/issues/55065>`_. - - Skip rebuilding lambda expressions in arguments of immediate invocations. This fixes `GH56183 <https://github.com/llvm/llvm-project/issues/56183>`_, `GH51695 <https://github.com/llvm/llvm-project/issues/51695>`_, `GH50455 <https://github.com/llvm/llvm-project/issues/50455>`_, `GH54872 <https://github.com/llvm/llvm-project/issues/54872>`_, `GH54587 <https://github.com/llvm/llvm-project/issues/54587>`_. +- Fixed a crash during template instantiation on a conversion operator during constraint + evaulation. Fixes `GH50891 <https://github.com/llvm/llvm-project/issues/50891>`_. C++2b Feature Support ^^^^^^^^^^^^^^^^^^^^^
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits