Skip to content

Commit 805d563

Browse files
authored
[clang] Mark ill-formed partial specialization as invalid (#89536)
Fixes #89374 Solution suggested by @cor3ntin
1 parent 6493da7 commit 805d563

File tree

4 files changed

+36
-0
lines changed

4 files changed

+36
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,9 @@ Bug Fixes in This Version
415415
operator.
416416
Fixes (#GH83267).
417417

418+
- Fix crash on ill-formed partial specialization with CRTP.
419+
Fixes (#GH89374).
420+
418421
- Clang now correctly generates overloads for bit-precise integer types for
419422
builtin operators in C++. Fixes #GH82998.
420423

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9460,6 +9460,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
94609460
Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
94619461
<< ClassTemplate->getDeclName();
94629462
isPartialSpecialization = false;
9463+
Invalid = true;
94639464
}
94649465
}
94659466

@@ -9675,6 +9676,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
96759676
if (SkipBody && SkipBody->ShouldSkip)
96769677
return SkipBody->Previous;
96779678

9679+
Specialization->setInvalidDecl(Invalid);
96789680
return Specialization;
96799681
}
96809682

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,6 +1914,9 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
19141914
if (!S.isCompleteType(Info.getLocation(), A))
19151915
return Result;
19161916

1917+
if (getCanonicalRD(A)->isInvalidDecl())
1918+
return Result;
1919+
19171920
// Reset the incorrectly deduced argument from above.
19181921
Deduced = DeducedOrig;
19191922

clang/test/SemaCXX/template-specialization.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,31 @@ void instantiate() {
5252
}
5353

5454
}
55+
56+
namespace GH89374 {
57+
58+
struct A {};
59+
60+
template <typename Derived>
61+
struct MatrixBase { // #GH89374-MatrixBase
62+
template <typename OtherDerived>
63+
Derived &operator=(const MatrixBase<OtherDerived> &); // #GH89374-copy-assignment
64+
};
65+
66+
template <typename>
67+
struct solve_retval;
68+
69+
template <typename Rhs>
70+
struct solve_retval<int> : MatrixBase<solve_retval<Rhs> > {};
71+
// expected-error@-1 {{partial specialization of 'solve_retval' does not use any of its template parameters}}
72+
73+
void ApproximateChebyshev() {
74+
MatrixBase<int> c;
75+
c = solve_retval<int>();
76+
// expected-error@-1 {{no viable overloaded '='}}
77+
// expected-note@#GH89374-copy-assignment {{candidate template ignored: could not match 'MatrixBase' against 'solve_retval'}}
78+
// 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}}
79+
// 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}}
80+
}
81+
82+
} // namespace GH89374

0 commit comments

Comments
 (0)