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

View File

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

View File

@@ -53,4 +53,15 @@ func main() {
let _ = Class1() 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() main()
foo()