[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.
This commit is contained in:
Vedant Kumar
2016-02-12 21:12:33 -08:00
parent 7b34ea9296
commit c5873f3683
3 changed files with 27 additions and 11 deletions

View File

@@ -30,13 +30,14 @@ using namespace swift;
using namespace Lowering;
static bool isUnmappedDecl(Decl *D) {
return (D->isImplicit() && !isa<ConstructorDecl>(D) &&
!isa<DestructorDecl>(D)) ||
isa<EnumCaseDecl>(D);
if (isa<ConstructorDecl>(D) || isa<DestructorDecl>(D))
return false;
return D->isImplicit() || isa<EnumCaseDecl>(D);
}
ProfilerRAII::ProfilerRAII(SILGenModule &SGM, AbstractFunctionDecl *D)
: SGM(SGM) {
: SGM(SGM), PreviousProfiler(std::move(SGM.Profiler)) {
const auto &Opts = SGM.M.getOptions();
if (!Opts.GenerateProfile || isUnmappedDecl(D))
return;
@@ -45,7 +46,7 @@ ProfilerRAII::ProfilerRAII(SILGenModule &SGM, AbstractFunctionDecl *D)
SGM.Profiler->assignRegionCounters(D);
}
ProfilerRAII::~ProfilerRAII() { SGM.Profiler = nullptr; }
ProfilerRAII::~ProfilerRAII() { SGM.Profiler = std::move(PreviousProfiler); }
namespace {

View File

@@ -27,12 +27,7 @@ namespace Lowering {
class SILGenModule;
class SILGenBuilder;
/// RAII object to set up profiling for a function.
struct ProfilerRAII {
SILGenModule &SGM;
ProfilerRAII(SILGenModule &SGM, AbstractFunctionDecl *D);
~ProfilerRAII();
};
struct ProfilerRAII;
/// Profiling state.
class SILGenProfiling {
@@ -67,6 +62,15 @@ private:
friend struct ProfilerRAII;
};
/// RAII object to set up profiling for a function.
struct ProfilerRAII {
SILGenModule &SGM;
std::unique_ptr<SILGenProfiling> PreviousProfiler;
ProfilerRAII(SILGenModule &SGM, AbstractFunctionDecl *D);
~ProfilerRAII();
};
} // end namespace Lowering
} // end namespace swift

View File

@@ -53,4 +53,15 @@ func main() {
let _ = Class1()
}
// rdar://problem/22761498 - enum declaration suppresses coverage
func foo() {
var x : Int32 = 0 // CHECK-COV: 1|{{.*}}[[@LINE]]
enum ETy { case A } // CHECK-COV: 1|{{.*}}[[@LINE]]
repeat { // CHECK-COV: 1|{{.*}}[[@LINE]]
x += 1 // CHECK-COV: 1|{{.*}}[[@LINE]]
} while x == 0 // CHECK-COV: 1|{{.*}}[[@LINE]]
x += 1 // CHECK-COV: 1|{{.*}}[[@LINE]]
}
main()
foo()