[llvm] 97c742e - [llvm-cov] Fix illegal cast from uint64_t to int64_t

Sajjad Mirza via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 15 18:14:16 PST 2019


Author: Sajjad Mirza
Date: 2019-11-15T18:13:45-08:00
New Revision: 97c742e6b74e731afdef74dd5f8366ce883e0520

URL: https://github.com/llvm/llvm-project/commit/97c742e6b74e731afdef74dd5f8366ce883e0520
DIFF: https://github.com/llvm/llvm-project/commit/97c742e6b74e731afdef74dd5f8366ce883e0520.diff

LOG: [llvm-cov] Fix illegal cast from uint64_t to int64_t

Summary:
Counters are stored as uint64_t in the coverage mapping, but
exporting in JSON requires signed integers. Clamp the values to the
smaller range to make the conversion safe.

Reviewers: Dor1s, vsk

Reviewed By: Dor1s

Subscribers: llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D70200

Added: 
    

Modified: 
    llvm/tools/llvm-cov/CoverageExporterJson.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/tools/llvm-cov/CoverageExporterJson.cpp b/llvm/tools/llvm-cov/CoverageExporterJson.cpp
index 181d428ed9d8..216b5e3fd226 100644
--- a/llvm/tools/llvm-cov/CoverageExporterJson.cpp
+++ b/llvm/tools/llvm-cov/CoverageExporterJson.cpp
@@ -48,6 +48,7 @@
 #include "llvm/Support/ThreadPool.h"
 #include "llvm/Support/Threading.h"
 #include <algorithm>
+#include <limits>
 #include <mutex>
 #include <utility>
 
@@ -61,14 +62,23 @@ using namespace llvm;
 
 namespace {
 
+// The JSON library accepts int64_t, but profiling counts are stored as uint64_t.
+// Therefore we need to explicitly convert from unsigned to signed, since a naive
+// cast is implementation-defined behavior when the unsigned value cannot be
+// represented as a signed value. We choose to clamp the values to preserve the
+// invariant that counts are always >= 0.
+int64_t clamp_uint64_to_int64(uint64_t u) {
+  return std::min(u, static_cast<uint64_t>(std::numeric_limits<int64_t>::max()));
+}
+
 json::Array renderSegment(const coverage::CoverageSegment &Segment) {
-  return json::Array({Segment.Line, Segment.Col, int64_t(Segment.Count),
+  return json::Array({Segment.Line, Segment.Col, clamp_uint64_to_int64(Segment.Count),
                       Segment.HasCount, Segment.IsRegionEntry});
 }
 
 json::Array renderRegion(const coverage::CountedRegion &Region) {
   return json::Array({Region.LineStart, Region.ColumnStart, Region.LineEnd,
-                      Region.ColumnEnd, int64_t(Region.ExecutionCount),
+                      Region.ColumnEnd, clamp_uint64_to_int64(Region.ExecutionCount),
                       Region.FileID, Region.ExpandedFileID,
                       int64_t(Region.Kind)});
 }
@@ -182,7 +192,7 @@ json::Array renderFunctions(
   for (const auto &F : Functions)
     FunctionArray.push_back(
         json::Object({{"name", F.Name},
-                      {"count", int64_t(F.ExecutionCount)},
+                      {"count", clamp_uint64_to_int64(F.ExecutionCount)},
                       {"regions", renderRegions(F.CountedRegions)},
                       {"filenames", json::Array(F.Filenames)}}));
   return FunctionArray;


        


More information about the llvm-commits mailing list