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.
|
// or the original C type.
|
||||||
clang::QualType ClangType = Decl->getUnderlyingType();
|
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(
|
SwiftType = Impl.importTypeIgnoreIUO(
|
||||||
ClangType, ImportTypeKind::Typedef,
|
ClangType, ImportTypeKind::Typedef,
|
||||||
ImportDiagnosticAdder(Impl, Decl, Decl->getLocation()),
|
ImportDiagnosticAdder(Impl, Decl, Decl->getLocation()),
|
||||||
@@ -3346,6 +3329,15 @@ namespace {
|
|||||||
decl->getName() == "_Expr" || decl->getName() == "__val_expr"))
|
decl->getName() == "_Expr" || decl->getName() == "__val_expr"))
|
||||||
return nullptr;
|
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
|
// `decl->getDefinition()` can return nullptr before the call to sema and
|
||||||
// return its definition afterwards.
|
// return its definition afterwards.
|
||||||
clang::Sema &clangSema = Impl.getClangSema();
|
clang::Sema &clangSema = Impl.getClangSema();
|
||||||
|
|||||||
@@ -60,4 +60,11 @@ struct PartialTemplate<T*, double> {
|
|||||||
};
|
};
|
||||||
typedef PartialTemplate<int*, double> CompletePartial;
|
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
|
#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
|
import ForwardDeclaredSpecialization
|
||||||
|
|
||||||
@@ -30,3 +30,17 @@ func testCompletePartial(_ param: CompletePartial) {
|
|||||||
let _ = param.ptr
|
let _ = param.ptr
|
||||||
let _ = param.value
|
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