mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #86002 from j-hui/migrate-incomplete-template-spec-check
This commit is contained in:
@@ -1501,23 +1501,6 @@ namespace {
|
||||
// or the original C type.
|
||||
clang::QualType ClangType = Decl->getUnderlyingType();
|
||||
|
||||
// Prevent import of typedefs to forward-declared explicit template
|
||||
// specializations, which would trigger assertion in Clang.
|
||||
if (auto *templateSpec = dyn_cast<clang::TemplateSpecializationType>(
|
||||
importer::desugarIfElaborated(ClangType).getTypePtr())) {
|
||||
if (auto *recordType =
|
||||
templateSpec->desugar()->getAs<clang::RecordType>()) {
|
||||
if (auto *spec = dyn_cast<clang::ClassTemplateSpecializationDecl>(
|
||||
recordType->getDecl())) {
|
||||
if (spec->getSpecializationKind() ==
|
||||
clang::TSK_ExplicitSpecialization &&
|
||||
!spec->isCompleteDefinition()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwiftType = Impl.importTypeIgnoreIUO(
|
||||
ClangType, ImportTypeKind::Typedef,
|
||||
ImportDiagnosticAdder(Impl, Decl, Decl->getLocation()),
|
||||
@@ -3346,6 +3329,15 @@ namespace {
|
||||
decl->getName() == "_Expr" || decl->getName() == "__val_expr"))
|
||||
return nullptr;
|
||||
|
||||
// Don't even try to specialize/import this template if it's
|
||||
// a forward-declared specialization like this:
|
||||
//
|
||||
// template <> struct MyTemplate<int>;
|
||||
//
|
||||
if (decl->getSpecializationKind() == clang::TSK_ExplicitSpecialization &&
|
||||
!decl->isCompleteDefinition())
|
||||
return nullptr;
|
||||
|
||||
// `decl->getDefinition()` can return nullptr before the call to sema and
|
||||
// return its definition afterwards.
|
||||
clang::Sema &clangSema = Impl.getClangSema();
|
||||
|
||||
@@ -60,4 +60,11 @@ struct PartialTemplate<T*, double> {
|
||||
};
|
||||
typedef PartialTemplate<int*, double> CompletePartial;
|
||||
|
||||
// Some functions that use forward-declared specializations
|
||||
void TakesIncompleteSpecialization(BasicTemplate<int>);
|
||||
BasicTemplate<int> ReturnsIncompleteSpecialization();
|
||||
|
||||
void TakesPtrToIncompleteSpecialization(BasicTemplate<int> *);
|
||||
BasicTemplate<int> *ReturnsPtrToIncompleteSpecialization();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=default
|
||||
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=default -suppress-remarks -suppress-notes
|
||||
|
||||
import ForwardDeclaredSpecialization
|
||||
|
||||
@@ -30,3 +30,17 @@ func testCompletePartial(_ param: CompletePartial) {
|
||||
let _ = param.ptr
|
||||
let _ = param.value
|
||||
}
|
||||
|
||||
func testFunctionsUsingIncompleteSpec() {
|
||||
let inc = ReturnsIncompleteSpecialization()
|
||||
// expected-error@-1 {{return type is unavailable in Swift}}
|
||||
// expected-warning@-2 {{constant 'inc' inferred to have type 'Never', which is an enum with no cases}}
|
||||
TakesIncompleteSpecialization(inc)
|
||||
// expected-error@-1 {{cannot find 'TakesIncompleteSpecialization' in scope}}
|
||||
}
|
||||
|
||||
func testFunctionsUsingPtrToIncompleteSpec(_ ptr: OpaquePointer) {
|
||||
let incPtr = ReturnsPtrToIncompleteSpecialization()
|
||||
TakesPtrToIncompleteSpecialization(incPtr)
|
||||
TakesPtrToIncompleteSpecialization(ptr)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user