Author: Vlad Serebrennikov Date: 2024-04-24T10:45:38+04:00 New Revision: 805d5637a0d50caa073f435b55940c1338aae0fc
URL: https://github.com/llvm/llvm-project/commit/805d5637a0d50caa073f435b55940c1338aae0fc DIFF: https://github.com/llvm/llvm-project/commit/805d5637a0d50caa073f435b55940c1338aae0fc.diff LOG: [clang] Mark ill-formed partial specialization as invalid (#89536) Fixes #89374 Solution suggested by @cor3ntin Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/SemaCXX/template-specialization.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3db558a1c11a3f..64526ed6d06f55 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -415,6 +415,9 @@ Bug Fixes in This Version operator. Fixes (#GH83267). +- Fix crash on ill-formed partial specialization with CRTP. + Fixes (#GH89374). + - Clang now correctly generates overloads for bit-precise integer types for builtin operators in C++. Fixes #GH82998. diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 4bda31ba67c02d..bbcb7c33a98579 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -9460,6 +9460,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized) << ClassTemplate->getDeclName(); isPartialSpecialization = false; + Invalid = true; } } @@ -9675,6 +9676,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( if (SkipBody && SkipBody->ShouldSkip) return SkipBody->Previous; + Specialization->setInvalidDecl(Invalid); return Specialization; } diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 0b6375001f5326..c3815bca038554 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -1914,6 +1914,9 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( if (!S.isCompleteType(Info.getLocation(), A)) return Result; + if (getCanonicalRD(A)->isInvalidDecl()) + return Result; + // Reset the incorrectly deduced argument from above. Deduced = DeducedOrig; diff --git a/clang/test/SemaCXX/template-specialization.cpp b/clang/test/SemaCXX/template-specialization.cpp index 7b26ff9f5c5ba4..eabb84f2e13d3e 100644 --- a/clang/test/SemaCXX/template-specialization.cpp +++ b/clang/test/SemaCXX/template-specialization.cpp @@ -52,3 +52,31 @@ void instantiate() { } } + +namespace GH89374 { + +struct A {}; + +template <typename Derived> +struct MatrixBase { // #GH89374-MatrixBase + template <typename OtherDerived> + Derived &operator=(const MatrixBase<OtherDerived> &); // #GH89374-copy-assignment +}; + +template <typename> +struct solve_retval; + +template <typename Rhs> +struct solve_retval<int> : MatrixBase<solve_retval<Rhs> > {}; +// expected-error@-1 {{partial specialization of 'solve_retval' does not use any of its template parameters}} + +void ApproximateChebyshev() { + MatrixBase<int> c; + c = solve_retval<int>(); + // expected-error@-1 {{no viable overloaded '='}} + // expected-note@#GH89374-copy-assignment {{candidate template ignored: could not match 'MatrixBase' against 'solve_retval'}} + // expected-note@#GH89374-MatrixBase {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'solve_retval<int>' to 'const MatrixBase<int>' for 1st argument}} + // expected-note@#GH89374-MatrixBase {{candidate function (the implicit move assignment operator) not viable: no known conversion from 'solve_retval<int>' to 'MatrixBase<int>' for 1st argument}} +} + +} // namespace GH89374 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits