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
24static Object serialize(const EntitySummary &S,
25 JSONFormat::EntityIdToJSONFn Fn) {
26 const auto &SS = static_cast<const UnsafeBufferUsageEntitySummary &>(S);
27 Array UnsafeBuffersData;
28
29 for (const auto &EPL : getUnsafeBuffers(SS))
30 UnsafeBuffersData.push_back(E: entityPointerLevelToJSON(EPL, EntityId2JSON: Fn));
31 return Object{{.K: SummarySerializationKey.data(), .V: std::move(UnsafeBuffersData)}};
32}
33
34static llvm::Expected<std::unique_ptr<EntitySummary>>
35deserializeImpl(const Object &Data, JSONFormat::EntityIdFromJSONFn Fn) {
36 const Array *UnsafeBuffersData =
37 Data.getArray(K: SummarySerializationKey.data());
38
39 if (!UnsafeBuffersData)
40 return makeSawButExpectedError(Saw: Object(Data), Expected: "an Object with a key %s",
41 ExpectedArgs: SummarySerializationKey.data());
42
43 EntityPointerLevelSet EPLs;
44
45 for (const auto &EltData : *UnsafeBuffersData) {
46 llvm::Expected<EntityPointerLevel> EPL =
47 entityPointerLevelFromJSON(EPLData: EltData, EntityIdFromJSON: Fn);
48
49 if (!EPL)
50 return EPL.takeError();
51 EPLs.insert(x: *EPL);
52 }
53 return std::make_unique<UnsafeBufferUsageEntitySummary>(
54 args: buildUnsafeBufferUsageEntitySummary(std::move(EPLs)));
55}
56
57static llvm::Expected<std::unique_ptr<EntitySummary>>
58deserialize(const Object &Data, EntityIdTable &,
59 JSONFormat::EntityIdFromJSONFn Fn) {
60 return deserializeImpl(Data, Fn);
61}
62
63namespace {
64struct UnsafeBufferUsageJSONFormatInfo final : JSONFormat::FormatInfo {
65 UnsafeBufferUsageJSONFormatInfo()
66 : JSONFormat::FormatInfo(UnsafeBufferUsageEntitySummary::summaryName(),
67 serialize, deserialize) {}
68};
69} // namespace
70
71static llvm::Registry<JSONFormat::FormatInfo>::Add<
72 UnsafeBufferUsageJSONFormatInfo>
73 RegisterUnsafeBufferUsageJSONFormatInfo(
74 UnsafeBufferUsageEntitySummary::Name,
75 "JSON Format info for UnsafeBufferUsageEntitySummary");
76
77namespace clang::ssaf {
78// NOLINTNEXTLINE(misc-use-internal-linkage)
79volatile int UnsafeBufferUsageJSONFormatAnchorSource = 0;
80} // namespace clang::ssaf
81