1//===- UnsafeBufferUsageFormat.cpp ----------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "SSAFAnalysesCommon.h"
10#include "clang/ScalableStaticAnalysis/Analyses/EntityPointerLevel/EntityPointerLevel.h"
11#include "clang/ScalableStaticAnalysis/Analyses/EntityPointerLevel/EntityPointerLevelFormat.h"
12#include "clang/ScalableStaticAnalysis/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h"
13#include "clang/ScalableStaticAnalysis/Core/Serialization/JSONFormat.h"
14#include "llvm/Support/Error.h"
15#include "llvm/Support/JSON.h"
16
17using namespace clang;
18using namespace ssaf;
19using Array = llvm::json::Array;
20using Object = llvm::json::Object;
21
22static constexpr llvm::StringLiteral SummarySerializationKey = "UnsafeBuffers";
23
24extern UnsafeBufferUsageEntitySummary
25ssaf::buildUnsafeBufferUsageEntitySummary(EntityPointerLevelSet UnsafeBuffers);
26
27extern llvm::iterator_range<EntityPointerLevelSet::const_iterator>
28ssaf::getUnsafeBuffers(const UnsafeBufferUsageEntitySummary &S);
29
30static Object serialize(const EntitySummary &S,
31 JSONFormat::EntityIdToJSONFn Fn) {
32 const auto &SS = static_cast<const UnsafeBufferUsageEntitySummary &>(S);
33 Array UnsafeBuffersData;
34
35 for (const auto &EPL : getUnsafeBuffers(S: SS))
36 UnsafeBuffersData.push_back(E: entityPointerLevelToJSON(EPL, EntityId2JSON: Fn));
37 return Object{{.K: SummarySerializationKey.data(), .V: std::move(UnsafeBuffersData)}};
38}
39
40static llvm::Expected<std::unique_ptr<EntitySummary>>
41deserializeImpl(const Object &Data, JSONFormat::EntityIdFromJSONFn Fn) {
42 const Array *UnsafeBuffersData =
43 Data.getArray(K: SummarySerializationKey.data());
44
45 if (!UnsafeBuffersData)
46 return makeSawButExpectedError(Saw: Object(Data), Expected: "an Object with a key %s",
47 ExpectedArgs: SummarySerializationKey.data());
48
49 EntityPointerLevelSet EPLs;
50
51 for (const auto &EltData : *UnsafeBuffersData) {
52 llvm::Expected<EntityPointerLevel> EPL =
53 entityPointerLevelFromJSON(EPLData: EltData, EntityIdFromJSON: Fn);
54
55 if (!EPL)
56 return EPL.takeError();
57 EPLs.insert(x: *EPL);
58 }
59 return std::make_unique<UnsafeBufferUsageEntitySummary>(
60 args: buildUnsafeBufferUsageEntitySummary(UnsafeBuffers: std::move(EPLs)));
61}
62
63static llvm::Expected<std::unique_ptr<EntitySummary>>
64deserialize(const Object &Data, EntityIdTable &,
65 JSONFormat::EntityIdFromJSONFn Fn) {
66 return deserializeImpl(Data, Fn);
67}
68
69namespace {
70struct UnsafeBufferUsageJSONFormatInfo final : JSONFormat::FormatInfo {
71 UnsafeBufferUsageJSONFormatInfo()
72 : JSONFormat::FormatInfo(UnsafeBufferUsageEntitySummary::summaryName(),
73 serialize, deserialize) {}
74};
75} // namespace
76
77static llvm::Registry<JSONFormat::FormatInfo>::Add<
78 UnsafeBufferUsageJSONFormatInfo>
79 RegisterUnsafeBufferUsageJSONFormatInfo(
80 UnsafeBufferUsageEntitySummary::Name,
81 "JSON Format info for UnsafeBufferUsageEntitySummary");
82
83namespace clang::ssaf {
84// NOLINTNEXTLINE(misc-use-internal-linkage)
85volatile int UnsafeBufferUsageJSONFormatAnchorSource = 0;
86} // namespace clang::ssaf
87