diff options
author | Sajjad Mirza <sajjadm@google.com> | 2019-11-15 18:09:53 -0800 |
---|---|---|
committer | Sajjad Mirza <sajjadm@google.com> | 2019-11-15 18:13:45 -0800 |
commit | 97c742e6b74e731afdef74dd5f8366ce883e0520 (patch) | |
tree | 4c1c85397c88aeff6cf10bb2345b706b58362afb /llvm/tools/llvm-cov/CoverageExporterJson.cpp | |
parent | 2c7c528d7ac17230f1f239b629a02d407a74e1bf (diff) | |
download | bcm5719-llvm-97c742e6b74e731afdef74dd5f8366ce883e0520.tar.gz bcm5719-llvm-97c742e6b74e731afdef74dd5f8366ce883e0520.zip |
[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
Diffstat (limited to 'llvm/tools/llvm-cov/CoverageExporterJson.cpp')
-rw-r--r-- | llvm/tools/llvm-cov/CoverageExporterJson.cpp | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/llvm/tools/llvm-cov/CoverageExporterJson.cpp b/llvm/tools/llvm-cov/CoverageExporterJson.cpp index 181d428ed9d..216b5e3fd22 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; |