Skip to content

Commit a437c6d

Browse files
authored
Merge pull request #85681 from allevato/more-json-ast-fixes
[ASTDumper] Fix some more JSON AST dump crashes.
2 parents 18faa24 + 8805d94 commit a437c6d

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

lib/AST/ASTDumper.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,12 @@ std::string typeUSR(Type type) {
260260
if (!type)
261261
return "";
262262

263+
if (type->is<ModuleType>()) {
264+
// ASTMangler does not support "module types". This can appear, for
265+
// example, on the left-hand side of a `DotSyntaxBaseIgnoredExpr` for a
266+
// module-qualified free function call: `Swift.print()`.
267+
return "";
268+
}
263269
if (type->hasArchetype()) {
264270
type = type->mapTypeOutOfEnvironment();
265271
}
@@ -280,6 +286,13 @@ std::string declTypeUSR(const ValueDecl *D) {
280286
if (!D)
281287
return "";
282288

289+
if (isa<ModuleDecl>(D)) {
290+
// ASTMangler does not support "module types". This can appear, for
291+
// example, on the left-hand side of a `DotSyntaxBaseIgnoredExpr` for a
292+
// module-qualified free function call: `Swift.print()`.
293+
return "";
294+
}
295+
283296
std::string usr;
284297
llvm::raw_string_ostream os(usr);
285298
if (swift::ide::printDeclTypeUSR(D, os))
@@ -1471,7 +1484,11 @@ namespace {
14711484
printFlag(value.isLocalCapture(), "is_local_capture");
14721485
printFlag(value.isDynamicSelfMetadata(), "is_dynamic_self_metadata");
14731486
if (auto *D = value.getDecl()) {
1474-
printRec(D, Label::always("decl"));
1487+
// We print the decl ref, not the full decl, to avoid infinite
1488+
// recursion when a function captures itself (and also because
1489+
// those decls are already printed elsewhere, so we don't need to
1490+
// print what could be a very large amount of information twice).
1491+
printDeclRefField(D, Label::always("decl"));
14751492
}
14761493
if (auto *E = value.getExpr()) {
14771494
printRec(E, Label::always("expr"));

test/Frontend/ast-dump-json-no-crash.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,3 +484,22 @@ dynamic func toBeReplaced(arg: Int) {}
484484

485485
@_dynamicReplacement(for: toBeReplaced(arg:))
486486
func toReplaceWith(arg: Int) {}
487+
488+
// Regression test: Swift 6.2 and earlier crashed trying to form the type USR
489+
// of the "module type" of a `DotSyntaxBaseIgnoredExpr` when calling a
490+
// module-qualified free function.
491+
func moduleTypeUSRRegressionTest() {
492+
Swift.print("")
493+
}
494+
495+
// Regression test: When a function captures another function, don't print the
496+
// entire captured decl. This causes infinite recursion in the dumper when a
497+
// local (nested) function captures itself.
498+
func outerFn() {
499+
func innerFun(shouldRecurse: Bool) {
500+
if shouldRecurse {
501+
innerFun(shouldRecurse: false)
502+
}
503+
}
504+
innerFun(shouldRecurse: true)
505+
}

0 commit comments

Comments
 (0)