luken-google updated this revision to Diff 457262. luken-google added a comment.
Refactor to use CodeSynthesisContexts 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/test/SemaTemplate/concepts.cpp Index: clang/test/SemaTemplate/concepts.cpp =================================================================== --- clang/test/SemaTemplate/concepts.cpp +++ clang/test/SemaTemplate/concepts.cpp @@ -256,3 +256,20 @@ C auto **&j2 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}} C auto **&&j3 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}} } + +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/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -4009,6 +4009,16 @@ } } + if (!S.CodeSynthesisContexts.empty()) + llvm::errs() << "Kind: " << S.CodeSynthesisContexts.back().Kind << "\n"; + + // Avoid an infinite template expansion loop in requirements checking by + // skipping the conversion functions check. + bool InRequirementInstantiation = + !S.CodeSynthesisContexts.empty() && + S.CodeSynthesisContexts.back().Kind == + Sema::CodeSynthesisContext::RequirementInstantiation; + // FIXME: Work around a bug in C++17 guaranteed copy elision. // // When initializing an object of class type T by constructor @@ -4021,7 +4031,7 @@ // Note: SecondStepOfCopyInit is only ever true in this case when // evaluating whether to produce a C++98 compatibility warning. if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 && - !SecondStepOfCopyInit) { + !SecondStepOfCopyInit && !InRequirementInstantiation) { Expr *Initializer = Args[0]; auto *SourceRD = Initializer->getType()->getAsCXXRecordDecl(); if (SourceRD && S.isCompleteType(DeclLoc, Initializer->getType())) { Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -210,7 +210,8 @@ 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>`_. - +- 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 @@ -256,3 +256,20 @@ C auto **&j2 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}} C auto **&&j3 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}} } + +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/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -4009,6 +4009,16 @@ } } + if (!S.CodeSynthesisContexts.empty()) + llvm::errs() << "Kind: " << S.CodeSynthesisContexts.back().Kind << "\n"; + + // Avoid an infinite template expansion loop in requirements checking by + // skipping the conversion functions check. + bool InRequirementInstantiation = + !S.CodeSynthesisContexts.empty() && + S.CodeSynthesisContexts.back().Kind == + Sema::CodeSynthesisContext::RequirementInstantiation; + // FIXME: Work around a bug in C++17 guaranteed copy elision. // // When initializing an object of class type T by constructor @@ -4021,7 +4031,7 @@ // Note: SecondStepOfCopyInit is only ever true in this case when // evaluating whether to produce a C++98 compatibility warning. if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 && - !SecondStepOfCopyInit) { + !SecondStepOfCopyInit && !InRequirementInstantiation) { Expr *Initializer = Args[0]; auto *SourceRD = Initializer->getType()->getAsCXXRecordDecl(); if (SourceRD && S.isCompleteType(DeclLoc, Initializer->getType())) { Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -210,7 +210,8 @@ 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>`_. - +- 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