Skip to content

Commit 7b46d41

Browse files
committed
[DebugInfo] Fix infinite recursion when opaque return type is defined
inside function returning it A stack overflow would happen when the compiler tried emitting debug info for a function whose opaque return type was declared inside the function itself. This fixes the issue by emitting a forward declaration for the function before emitting it. rdar://150313956 (cherry picked from commit c03831f)
1 parent 88f32b3 commit 7b46d41

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
979979
if (Scope)
980980
return MainFile;
981981
}
982-
return cast<llvm::DIFile>(Scope);
982+
if (Scope)
983+
return cast<llvm::DIFile>(Scope);
984+
985+
return MainFile;
983986
}
984987

985988
static unsigned getStorageSizeInBits(const llvm::DataLayout &DL,
@@ -3222,6 +3225,11 @@ IRGenDebugInfoImpl::emitFunction(const SILDebugScope *DS, llvm::Function *Fn,
32223225
Name = LinkageName;
32233226
}
32243227

3228+
llvm::DISubprogram *ReplaceableType = DBuilder.createTempFunctionFwdDecl(
3229+
Scope, Name, LinkageName, File, Line, /*Type=*/nullptr, ScopeLine);
3230+
auto FwdDecl = llvm::TempDISubprogram(ReplaceableType);
3231+
ScopeCache[DS] = llvm::TrackingMDNodeRef(FwdDecl.get());
3232+
32253233
CanSILFunctionType FnTy = getFunctionType(SILTy);
32263234
auto Params = Opts.DebugInfoLevel > IRGenDebugInfoLevel::LineTables
32273235
? createParameterTypes(SILTy)
@@ -3321,6 +3329,7 @@ IRGenDebugInfoImpl::emitFunction(const SILDebugScope *DS, llvm::Function *Fn,
33213329
if (!DS)
33223330
return nullptr;
33233331

3332+
DBuilder.replaceTemporary(std::move(FwdDecl), SP);
33243333
ScopeCache[DS] = llvm::TrackingMDNodeRef(SP);
33253334
return SP;
33263335
}

test/DebugInfo/nested_opaque.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend -primary-file %s -emit-ir -g -o - | %FileCheck %s
2+
3+
protocol TheProtocol {
4+
}
5+
6+
// CHECK: ![[FUNC_ID:[0-9]+]] = distinct !DISubprogram(name: "theFunction",
7+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "TheType", scope: ![[FUNC_ID]]
8+
func theFunction() -> some TheProtocol {
9+
struct TheType: TheProtocol {
10+
}
11+
return TheType()
12+
}
13+
14+
theFunction()

0 commit comments

Comments
 (0)