Skip to content

Commit 747234c

Browse files
authored
Merge pull request #86002 from j-hui/migrate-incomplete-template-spec-check
2 parents f82cf1e + bb5bb97 commit 747234c

File tree

3 files changed

+31
-18
lines changed

3 files changed

+31
-18
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,23 +1501,6 @@ namespace {
15011501
// or the original C type.
15021502
clang::QualType ClangType = Decl->getUnderlyingType();
15031503

1504-
// Prevent import of typedefs to forward-declared explicit template
1505-
// specializations, which would trigger assertion in Clang.
1506-
if (auto *templateSpec = dyn_cast<clang::TemplateSpecializationType>(
1507-
importer::desugarIfElaborated(ClangType).getTypePtr())) {
1508-
if (auto *recordType =
1509-
templateSpec->desugar()->getAs<clang::RecordType>()) {
1510-
if (auto *spec = dyn_cast<clang::ClassTemplateSpecializationDecl>(
1511-
recordType->getDecl())) {
1512-
if (spec->getSpecializationKind() ==
1513-
clang::TSK_ExplicitSpecialization &&
1514-
!spec->isCompleteDefinition()) {
1515-
return nullptr;
1516-
}
1517-
}
1518-
}
1519-
}
1520-
15211504
SwiftType = Impl.importTypeIgnoreIUO(
15221505
ClangType, ImportTypeKind::Typedef,
15231506
ImportDiagnosticAdder(Impl, Decl, Decl->getLocation()),
@@ -3346,6 +3329,15 @@ namespace {
33463329
decl->getName() == "_Expr" || decl->getName() == "__val_expr"))
33473330
return nullptr;
33483331

3332+
// Don't even try to specialize/import this template if it's
3333+
// a forward-declared specialization like this:
3334+
//
3335+
// template <> struct MyTemplate<int>;
3336+
//
3337+
if (decl->getSpecializationKind() == clang::TSK_ExplicitSpecialization &&
3338+
!decl->isCompleteDefinition())
3339+
return nullptr;
3340+
33493341
// `decl->getDefinition()` can return nullptr before the call to sema and
33503342
// return its definition afterwards.
33513343
clang::Sema &clangSema = Impl.getClangSema();

test/Interop/Cxx/templates/Inputs/ForwardDeclaredSpecialization.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,11 @@ struct PartialTemplate<T*, double> {
6060
};
6161
typedef PartialTemplate<int*, double> CompletePartial;
6262

63+
// Some functions that use forward-declared specializations
64+
void TakesIncompleteSpecialization(BasicTemplate<int>);
65+
BasicTemplate<int> ReturnsIncompleteSpecialization();
66+
67+
void TakesPtrToIncompleteSpecialization(BasicTemplate<int> *);
68+
BasicTemplate<int> *ReturnsPtrToIncompleteSpecialization();
69+
6370
#endif

test/Interop/Cxx/templates/forward-declared-specialization.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=default
1+
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=default -suppress-remarks -suppress-notes
22

33
import ForwardDeclaredSpecialization
44

@@ -30,3 +30,17 @@ func testCompletePartial(_ param: CompletePartial) {
3030
let _ = param.ptr
3131
let _ = param.value
3232
}
33+
34+
func testFunctionsUsingIncompleteSpec() {
35+
let inc = ReturnsIncompleteSpecialization()
36+
// expected-error@-1 {{return type is unavailable in Swift}}
37+
// expected-warning@-2 {{constant 'inc' inferred to have type 'Never', which is an enum with no cases}}
38+
TakesIncompleteSpecialization(inc)
39+
// expected-error@-1 {{cannot find 'TakesIncompleteSpecialization' in scope}}
40+
}
41+
42+
func testFunctionsUsingPtrToIncompleteSpec(_ ptr: OpaquePointer) {
43+
let incPtr = ReturnsPtrToIncompleteSpecialization()
44+
TakesPtrToIncompleteSpecialization(incPtr)
45+
TakesPtrToIncompleteSpecialization(ptr)
46+
}

0 commit comments

Comments
 (0)