Skip to content

Commit 3a87cbe

Browse files
committed
[cxx-interop] Disable importing fully specialized class templates.
Before this patch we would crash when importing a fully specialized class template contianing a child declaration. This patch simply bails on fully-specialized class templates instead of potentially crashing.
1 parent f0f2246 commit 3a87cbe

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3544,6 +3544,14 @@ namespace {
35443544
auto def = dyn_cast<clang::ClassTemplateSpecializationDecl>(
35453545
decl->getDefinition());
35463546
assert(def && "Class template instantiation didn't have definition");
3547+
3548+
// If this type is fully specialized (i.e. "Foo<>" or "Foo<int, int>"),
3549+
// bail to prevent a crash.
3550+
// TODO: we should be able to support fully specialized class templates.
3551+
// See SR-13775 for more info.
3552+
if (def->getTypeAsWritten())
3553+
return nullptr;
3554+
35473555
// FIXME: This will instantiate all members of the specialization (and detect
35483556
// instantiation failures in them), which can be more than is necessary
35493557
// and is more than what Clang does. As a result we reject some C++

test/Interop/Cxx/templates/Inputs/explicit-class-specialization.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,39 @@ struct MagicWrapper<SpecializedIntWrapper> {
2626
typedef MagicWrapper<SpecializedIntWrapper> WrapperWithSpecialization;
2727
typedef MagicWrapper<NonSpecializedIntWrapper> WrapperWithoutSpecialization;
2828

29+
// Make sure these declarations don't cause a crash even though we can't import
30+
// them.
31+
32+
template <class...> class HasSpecializations;
33+
34+
template <> class HasSpecializations<> {
35+
int value;
36+
struct Child {};
37+
enum Maybe : int { No, Yes };
38+
};
39+
40+
template <> class HasSpecializations<int> {
41+
int value;
42+
struct Child {};
43+
enum Maybe : int { No, Yes };
44+
};
45+
46+
template <> class HasSpecializations<int, int> {
47+
int value;
48+
struct Child {};
49+
enum Maybe : int { No, Yes };
50+
};
51+
52+
template <class T> class HasSpecializations<T, int> {
53+
int value;
54+
struct Child {};
55+
enum Maybe : int { No, Yes };
56+
};
57+
58+
template <class T, class... Ts> class HasSpecializations<int, T, Ts...> {
59+
int value;
60+
struct Child {};
61+
enum Maybe : int { No, Yes };
62+
};
63+
2964
#endif // TEST_INTEROP_CXX_TEMPLATES_INPUTS_EXPLICIT_SPECIALIZATION_H

test/Interop/Cxx/templates/explicit-class-specialization.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import StdlibUnittest
88
var TemplatesTestSuite = TestSuite("TemplatesTestSuite")
99

1010
TemplatesTestSuite.test("explicit-specialization") {
11-
let specializedInt = SpecializedIntWrapper(value: 7)
12-
var specializedMagicInt = WrapperWithSpecialization(t: specializedInt)
13-
expectEqual(specializedMagicInt.doubleIfSpecializedElseTriple(), 14)
11+
// TODO: re-enable this test once SR-13775 is resolved.
12+
// let specializedInt = SpecializedIntWrapper(value: 7)
13+
// var specializedMagicInt = WrapperWithSpecialization(t: specializedInt)
14+
// expectEqual(specializedMagicInt.doubleIfSpecializedElseTriple(), 14)
1415

1516
let nonSpecializedInt = NonSpecializedIntWrapper(value: 7)
1617
var nonSpecializedMagicInt = WrapperWithoutSpecialization(t: nonSpecializedInt)

0 commit comments

Comments
 (0)