GCOVProfiling: Avoid use-after-move
authorDavid Blaikie <dblaikie@gmail.com>
Sun, 13 Sep 2020 19:54:36 +0000 (12:54 -0700)
committerDavid Blaikie <dblaikie@gmail.com>
Sun, 13 Sep 2020 19:54:36 +0000 (12:54 -0700)
Turns out this was use-after-move of function_ref, which is trivially
copyable and movable, so the move did nothing and use after move was
safe.

But since this function_ref is being copied into a std::function, change
the function_ref to be std::function to avoid extra layers of type
erasure indirection - and then it's a real use after move, and fix that
by referring to the moved-to member variable rather than the moved-from
parameter.

llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp

index 68199f6379d40b9676269fafdd689f00129a5e39..c72c44809acc703c0c9652a8f360e7951d7db72c 100644 (file)
@@ -99,10 +99,10 @@ class GCOVProfiler {
 public:
   GCOVProfiler() : GCOVProfiler(GCOVOptions::getDefault()) {}
   GCOVProfiler(const GCOVOptions &Opts) : Options(Opts) {}
-  bool runOnModule(Module &M,
-                   function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
-                   function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
-                   function_ref<const TargetLibraryInfo &(Function &F)> GetTLI);
+  bool
+  runOnModule(Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
+              function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
+              std::function<const TargetLibraryInfo &(Function &F)> GetTLI);
 
   void write(uint32_t i) {
     char Bytes[4];
@@ -609,7 +609,7 @@ std::string GCOVProfiler::mangleName(const DICompileUnit *CU,
 bool GCOVProfiler::runOnModule(
     Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
     function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
-    function_ref<const TargetLibraryInfo &(Function &F)> GetTLI) {
+    std::function<const TargetLibraryInfo &(Function &F)> GetTLI) {
   this->M = &M;
   this->GetTLI = std::move(GetTLI);
   Ctx = &M.getContext();
@@ -622,7 +622,7 @@ bool GCOVProfiler::runOnModule(
 
   FilterRe = createRegexesFromString(Options.Filter);
   ExcludeRe = createRegexesFromString(Options.Exclude);
-  emitProfileNotes(CUNode, HasExecOrFork, GetBFI, GetBPI, GetTLI);
+  emitProfileNotes(CUNode, HasExecOrFork, GetBFI, GetBPI, this->GetTLI);
   return true;
 }