clang 23.0.0git
UnsafeBufferUsage.cpp
Go to the documentation of this file.
1//===- UnsafeBufferUsage.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
13#include "llvm/Support/Error.h"
14#include "llvm/Support/JSON.h"
15#include <cstdint>
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
24EntityPointerLevel ssaf::buildEntityPointerLevel(EntityId Id, unsigned PtrLv) {
25 return EntityPointerLevel(Id, PtrLv);
26}
27
29ssaf::buildUnsafeBufferUsageEntitySummary(EntityPointerLevelSet UnsafeBuffers) {
30 return UnsafeBufferUsageEntitySummary(std::move(UnsafeBuffers));
31}
32
33llvm::iterator_range<EntityPointerLevelSet::const_iterator>
34ssaf::getUnsafeBuffers(const UnsafeBufferUsageEntitySummary &S) {
35 return llvm::make_range(S.UnsafeBuffers.begin(), S.UnsafeBuffers.end());
36}
37
40 const auto &SS = static_cast<const UnsafeBufferUsageEntitySummary &>(S);
41 Array UnsafeBuffersData;
42
43 for (const auto &EPL : getUnsafeBuffers(SS))
44 UnsafeBuffersData.push_back(
45 Array{Fn(EPL.getEntity()), EPL.getPointerLevel()});
46 return Object{{SummarySerializationKey.data(), std::move(UnsafeBuffersData)}};
47}
48
51 const Array *UnsafeBuffersData =
52 Data.getArray(SummarySerializationKey.data());
53
54 if (!UnsafeBuffersData)
55 return llvm::createStringError("expected a json::Object with a key %s",
57
59
60 for (const auto &EltData : *UnsafeBuffersData) {
61 const Array *EltDataAsArr = EltData.getAsArray();
62
63 if (!EltDataAsArr || EltDataAsArr->size() != 2)
64 return llvm::createStringError("expected a json::Array of size 2");
65
66 const Object *IdData = (*EltDataAsArr)[0].getAsObject();
67 std::optional<uint64_t> PtrLvData = (*EltDataAsArr)[1].getAsInteger();
68
69 if (!IdData || !PtrLvData)
70 return llvm::createStringError("expected a json::Value of integer type");
71
72 llvm::Expected<EntityId> Id = Fn(*IdData);
73
74 if (!Id)
75 return Id.takeError();
76 EPLs.insert(buildEntityPointerLevel(Id.get(), *PtrLvData));
77 }
78 return std::make_unique<UnsafeBufferUsageEntitySummary>(
79 buildUnsafeBufferUsageEntitySummary(std::move(EPLs)));
80}
81
87
93
94static llvm::Registry<JSONFormat::FormatInfo>::Add<
98 "JSON Format info for UnsafeBufferUsageEntitySummary");
99
100// NOLINTNEXTLINE(misc-use-internal-linkage)
102
103// For unit test:
107 std::function<uint64_t(EntityId)> IdToIntFn,
108 std::function<llvm::Expected<EntityId>(uint64_t)> IdFromIntFn) {
109
110 auto IdToJson = [&IdToIntFn](EntityId Id) -> Object {
111 return Object({{"@", IdToIntFn(Id)}});
112 };
113 auto IdFromJson =
114 [&IdFromIntFn](const Object &O) -> llvm::Expected<EntityId> {
115 const auto *Int = O.get("@");
116
117 if (Int && Int->getAsUINT64())
118 return IdFromIntFn(*Int->getAsUINT64());
119 return llvm::createStringError("failed to get EntityId from Object");
120 };
121
122 return deserializeImpl(serialize(S, IdToJson), IdFromJson);
123}
volatile int UnsafeBufferUsageSSAFJSONFormatAnchorSource
static llvm::Expected< std::unique_ptr< EntitySummary > > deserialize(const Object &Data, EntityIdTable &, JSONFormat::EntityIdFromJSONFn Fn)
static llvm::Expected< std::unique_ptr< EntitySummary > > deserializeImpl(const Object &Data, JSONFormat::EntityIdFromJSONFn Fn)
static llvm::Registry< JSONFormat::FormatInfo >::Add< UnsafeBufferUsageJSONFormatInfo > RegisterUnsafeBufferUsageJSONFormatInfo(UnsafeBufferUsageEntitySummary::Name, "JSON Format info for UnsafeBufferUsageEntitySummary")
llvm::json::Object Object
static Object serialize(const EntitySummary &S, JSONFormat::EntityIdToJSONFn Fn)
static constexpr llvm::StringLiteral SummarySerializationKey
llvm::json::Array Array
std::set< EntityPointerLevel, EntityPointerLevel::Comparator > EntityPointerLevelSet
An UnsafeBufferUsageEntitySummary is an immutable set of unsafe buffers, in the form of EntityPointer...
static constexpr llvm::StringLiteral Name
Manages entity name interning and provides efficient EntityId handles.
Lightweight opaque handle representing an entity in an EntityIdTable.
Definition EntityId.h:31
Base class for analysis-specific summary data.
llvm::function_ref< llvm::Expected< EntityId >(const Object &)> EntityIdFromJSONFn
Definition JSONFormat.h:66
FormatInfoEntry< SerializerFn, DeserializerFn > FormatInfo
Definition JSONFormat.h:75
llvm::function_ref< Object(EntityId)> EntityIdToJSONFn
Definition JSONFormat.h:65
llvm::Expected< std::unique_ptr< EntitySummary > > serializeDeserializeRoundTrip(const UnsafeBufferUsageEntitySummary &S, std::function< uint64_t(EntityId)> IdToIntFn, std::function< llvm::Expected< EntityId >(uint64_t)> IdFromIntFn)
llvm::json::Object Object
The JSON file list parser is used to communicate input to InstallAPI.
int const char * function
Definition c++config.h:31