Skip to content

Commit c5873f3

Browse files
committed
[Coverage] Make ~ProfilerRAII restore the correct context
Swift permits function decls within function decls. ~ProfilerRAII would destroy the current profiling context upon entering a nested function decl instead of preserving it for later use. Fix the issue by recording the correct context in ProfilerRAII.
1 parent 7b34ea9 commit c5873f3

File tree

3 files changed

+27
-11
lines changed

3 files changed

+27
-11
lines changed

lib/SILGen/SILGenProfiling.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@ using namespace swift;
3030
using namespace Lowering;
3131

3232
static bool isUnmappedDecl(Decl *D) {
33-
return (D->isImplicit() && !isa<ConstructorDecl>(D) &&
34-
!isa<DestructorDecl>(D)) ||
35-
isa<EnumCaseDecl>(D);
33+
if (isa<ConstructorDecl>(D) || isa<DestructorDecl>(D))
34+
return false;
35+
36+
return D->isImplicit() || isa<EnumCaseDecl>(D);
3637
}
3738

3839
ProfilerRAII::ProfilerRAII(SILGenModule &SGM, AbstractFunctionDecl *D)
39-
: SGM(SGM) {
40+
: SGM(SGM), PreviousProfiler(std::move(SGM.Profiler)) {
4041
const auto &Opts = SGM.M.getOptions();
4142
if (!Opts.GenerateProfile || isUnmappedDecl(D))
4243
return;
@@ -45,7 +46,7 @@ ProfilerRAII::ProfilerRAII(SILGenModule &SGM, AbstractFunctionDecl *D)
4546
SGM.Profiler->assignRegionCounters(D);
4647
}
4748

48-
ProfilerRAII::~ProfilerRAII() { SGM.Profiler = nullptr; }
49+
ProfilerRAII::~ProfilerRAII() { SGM.Profiler = std::move(PreviousProfiler); }
4950

5051
namespace {
5152

lib/SILGen/SILGenProfiling.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,7 @@ namespace Lowering {
2727
class SILGenModule;
2828
class SILGenBuilder;
2929

30-
/// RAII object to set up profiling for a function.
31-
struct ProfilerRAII {
32-
SILGenModule &SGM;
33-
ProfilerRAII(SILGenModule &SGM, AbstractFunctionDecl *D);
34-
~ProfilerRAII();
35-
};
30+
struct ProfilerRAII;
3631

3732
/// Profiling state.
3833
class SILGenProfiling {
@@ -67,6 +62,15 @@ class SILGenProfiling {
6762
friend struct ProfilerRAII;
6863
};
6964

65+
/// RAII object to set up profiling for a function.
66+
struct ProfilerRAII {
67+
SILGenModule &SGM;
68+
std::unique_ptr<SILGenProfiling> PreviousProfiler;
69+
70+
ProfilerRAII(SILGenModule &SGM, AbstractFunctionDecl *D);
71+
~ProfilerRAII();
72+
};
73+
7074
} // end namespace Lowering
7175
} // end namespace swift
7276

test/SILGen/coverage_smoke.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,15 @@ func main() {
5353
let _ = Class1()
5454
}
5555

56+
// rdar://problem/22761498 - enum declaration suppresses coverage
57+
func foo() {
58+
var x : Int32 = 0 // CHECK-COV: 1|{{.*}}[[@LINE]]
59+
enum ETy { case A } // CHECK-COV: 1|{{.*}}[[@LINE]]
60+
repeat { // CHECK-COV: 1|{{.*}}[[@LINE]]
61+
x += 1 // CHECK-COV: 1|{{.*}}[[@LINE]]
62+
} while x == 0 // CHECK-COV: 1|{{.*}}[[@LINE]]
63+
x += 1 // CHECK-COV: 1|{{.*}}[[@LINE]]
64+
}
65+
5666
main()
67+
foo()

0 commit comments

Comments
 (0)