Skip to content

Commit 51dda66

Browse files
committed
[cxx-interop] Avoid importing too complex specializations
This reduces the specialization limit from 10000 to 1000 to prevent Swift from failing to import libstdc++ due to `std::_Index_tuple` being defined recursively. This also adds a diagnostic to let the user know why a template instantiation wasn't imported. rdar://96324175
1 parent c88a157 commit 51dda66

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

include/swift/AST/DiagnosticsClangImporter.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ WARNING(libstdcxx_not_found, none,
124124
"libstdc++ not found for '%0'; C++ stdlib may be unavailable",
125125
(StringRef))
126126

127+
WARNING(too_many_class_template_instantiations, none,
128+
"template instantiation for '%0' not imported: too many instantiations",
129+
(StringRef))
130+
127131
NOTE(macro_not_imported_unsupported_operator, none, "operator not supported in macro arithmetic", ())
128132
NOTE(macro_not_imported_unsupported_named_operator, none, "operator '%0' not supported in macro arithmetic", (StringRef))
129133
NOTE(macro_not_imported_invalid_string_literal, none, "invalid string literal", ())

lib/ClangImporter/ImportDecl.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2486,8 +2486,16 @@ namespace {
24862486
// deep/complex template, or we've run into an infinite loop. In either
24872487
// case, its not worth the compile time, so bail.
24882488
// TODO: this could be configurable at some point.
2489-
if (llvm::size(decl->getSpecializedTemplate()->specializations()) > 10000)
2489+
if (llvm::size(decl->getSpecializedTemplate()->specializations()) >
2490+
1000) {
2491+
std::string name;
2492+
llvm::raw_string_ostream os(name);
2493+
decl->printQualifiedName(os);
2494+
// Emit a warning if we haven't warned about this decl yet.
2495+
if (Impl.tooDeepTemplateSpecializations.insert(name).second)
2496+
Impl.diagnose({}, diag::too_many_class_template_instantiations, name);
24902497
return nullptr;
2498+
}
24912499

24922500
// `Sema::isCompleteType` will try to instantiate the class template as a
24932501
// side-effect and we rely on this here. `decl->getDefinition()` can

lib/ClangImporter/ImporterImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,10 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
626626
llvm::DenseMap<clang::FunctionDecl *, ValueDecl *>
627627
specializedFunctionTemplates;
628628

629+
/// Stores qualified names of C++ template specializations that were too deep
630+
/// to import into Swift.
631+
llvm::StringSet<> tooDeepTemplateSpecializations;
632+
629633
/// Keeps track of the Clang functions that have been turned into
630634
/// properties.
631635
llvm::DenseMap<const clang::FunctionDecl *, VarDecl *> FunctionsAsProperties;

0 commit comments

Comments
 (0)