mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[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:
@@ -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 {
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user