llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-ssaf Author: Ziqing Luo (ziqingluo-90) <details> <summary>Changes</summary> Implemented and registered a JSONFormat::FormatInfo for UnsafeBufferUsage analysis rdar://171920065 --- Patch is 59.79 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/187156.diff 17 Files Affected: - (modified) clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h (+8-1) - (renamed) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h (+40-32) - (added) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h (+40) - (removed) clang/include/clang/ScalableStaticAnalysisFramework/Core/Analyses/UnsafeBufferUsage/UnsafeBufferUsageBuilder.h (-32) - (modified) clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h (+4) - (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+43-16) - (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt (+16) - (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp (+89) - (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.cpp (+369) - (modified) clang/lib/ScalableStaticAnalysisFramework/CMakeLists.txt (+2) - (modified) clang/lib/ScalableStaticAnalysisFramework/Frontend/CMakeLists.txt (+1) - (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/tu-summary-serialization.test (+4) - (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/tu-summary.json (+108) - (modified) clang/test/Analysis/Scalable/ssaf-format/list.test (+2-1) - (modified) clang/tools/clang-ssaf-format/CMakeLists.txt (+2-1) - (modified) clang/tools/clang-ssaf-linker/CMakeLists.txt (+1) - (modified) clang/unittests/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageTest.cpp (+638-39) ``````````diff diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h index 876682ad779d4..e0d583c735e61 100644 --- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h +++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h @@ -201,7 +201,14 @@ bool anyConflict(const llvm::SmallVectorImpl<FixItHint> &FixIts, const SourceManager &SM); } // namespace internal -std::set<const Expr *> findUnsafePointers(const FunctionDecl *FD); +/// Find unsafe pointers in body/initializer of `D`, if `D` is one of the +/// followings: +/// VarDecl +/// FieldDecl +/// FunctionDecl +/// BlockDecl +/// ObjCMethodDecl +std::set<const Expr *> findUnsafePointers(const Decl *D); } // end namespace clang #endif /* LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H */ diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h similarity index 56% rename from clang/include/clang/ScalableStaticAnalysisFramework/Core/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h rename to clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h index 5b58ed0684333..2b36c47fe67a5 100644 --- a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h +++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGE_H -#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGE_H +#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGE_H +#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGE_H #include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h" #include "clang/ScalableStaticAnalysisFramework/Core/Model/SummaryName.h" +#include "clang/ScalableStaticAnalysisFramework/Core/Serialization/JSONFormat.h" #include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/EntitySummary.h" -#include "llvm/ADT/iterator_range.h" #include <set> namespace clang::ssaf { @@ -26,22 +26,19 @@ namespace clang::ssaf { /// *' of 'p'. /// /// An EntityPointerLevel can be identified by an EntityId and an unsigned -/// integer indicating the pointer level: '(EntityId, PointerLevel)'. An -/// EntityPointerLevel 'P' is valid iff -/// - 'P.EntityId' has a pointer type with at least 'P.PointerLevel' levels -/// (This implies 'P.PointerLevel > 0'); -/// - 'P.EntityId' identifies an lvalue object and 'P.PointerLevel == 0'. -/// The latter case represents address-of expressions. +/// integer indicating the pointer level: '(EntityId, PointerLevel)'. +/// An EntityPointerLevel 'P' is valid iff 'P.EntityId' has a pointer type with +/// at least 'P.PointerLevel' levels (This implies 'P.PointerLevel > 0'). /// /// For the same example 'int *p[10];', the EntityPointerLevels below are valid: -/// '(p, 1)' is associated with 'int *[10]' of 'p'; -/// '(p, 2)' is associated with 'int *' of 'p'; -/// '(p, 0)' represents '&p'. +/// - '(p, 2)' is associated with the 'int *' part of the declared type of 'p'; +/// - '(p, 1)' is associated with the 'int *[10]' part of the declared type of +/// 'p'. class EntityPointerLevel { EntityId Entity; unsigned PointerLevel; - friend class UnsafeBufferUsageTUSummaryBuilder; + friend class UnsafeBufferUsageTUSummaryExtractor; friend class UnsafeBufferUsageEntitySummary; EntityPointerLevel(EntityId Entity, unsigned PointerLevel) @@ -52,7 +49,8 @@ class EntityPointerLevel { unsigned getPointerLevel() const { return PointerLevel; } bool operator==(const EntityPointerLevel &Other) const { - return Entity == Other.Entity && PointerLevel == Other.PointerLevel; + return std::tie(Entity, PointerLevel) == + std::tie(Other.Entity, Other.PointerLevel); } bool operator!=(const EntityPointerLevel &Other) const { @@ -64,7 +62,8 @@ class EntityPointerLevel { std::tie(Other.Entity, Other.PointerLevel); } - // Comparator supporting partial comparison against EntityId: + /// Compares `EntityPointerLevel`s; additionally, partially compares + /// `EntityPointerLevel` with `EntityId`. struct Comparator { using is_transparent = void; bool operator()(const EntityPointerLevel &L, @@ -88,33 +87,42 @@ using EntityPointerLevelSet = class UnsafeBufferUsageEntitySummary final : public EntitySummary { const EntityPointerLevelSet UnsafeBuffers; - friend class UnsafeBufferUsageTUSummaryBuilder; + friend class UnsafeBufferUsageTUSummaryExtractor; - UnsafeBufferUsageEntitySummary(EntityPointerLevelSet &&UnsafeBuffers) + UnsafeBufferUsageEntitySummary(EntityPointerLevelSet UnsafeBuffers) : EntitySummary(), UnsafeBuffers(std::move(UnsafeBuffers)) {} public: - using const_iterator = EntityPointerLevelSet::const_iterator; - - const_iterator begin() const { return UnsafeBuffers.begin(); } - const_iterator end() const { return UnsafeBuffers.end(); } + SummaryName getSummaryName() const override { return summaryName(); }; - const_iterator find(const EntityPointerLevel &V) const { - return UnsafeBuffers.find(V); + bool operator==(const EntityPointerLevelSet &Other) const { + return UnsafeBuffers == Other; } - llvm::iterator_range<const_iterator> getSubsetOf(EntityId Entity) const { - return llvm::make_range(UnsafeBuffers.equal_range(Entity)); + bool operator==(const UnsafeBufferUsageEntitySummary &Other) const { + return UnsafeBuffers == Other.UnsafeBuffers; } - /// \return the size of the set of EntityLevelPointers, which represents the - /// set of unsafe buffers - size_t getNumUnsafeBuffers() { return UnsafeBuffers.size(); } + bool empty() const { return UnsafeBuffers.empty(); } - SummaryName getSummaryName() const override { - return SummaryName{"UnsafeBufferUsage"}; - }; + static llvm::json::Object + jsonSerializeFn(const EntitySummary &ES, + JSONFormat::EntityIdToJSONFn EntityId2JSON); + + static llvm::Expected<std::unique_ptr<EntitySummary>> + jsonDeserializeFn(const llvm::json::Object &Data, EntityIdTable &, + JSONFormat::EntityIdFromJSONFn EntityIdFromJSON); + + static SummaryName summaryName() { return SummaryName{"UnsafeBufferUsage"}; } +}; + +struct UnsafeBufferUsageJSONFormatInfo : JSONFormat::FormatInfo { + UnsafeBufferUsageJSONFormatInfo() + : JSONFormat::FormatInfo( + UnsafeBufferUsageEntitySummary::summaryName(), + UnsafeBufferUsageEntitySummary::jsonSerializeFn, + UnsafeBufferUsageEntitySummary::jsonDeserializeFn) {} }; } // namespace clang::ssaf -#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGE_H +#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGE_H diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h new file mode 100644 index 0000000000000..765b2c37562ce --- /dev/null +++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h @@ -0,0 +1,40 @@ +//===- UnsafeBufferUsageExtractor.h -----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H +#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H + +#include "clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h" +#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h" +#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityName.h" +#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/TUSummaryBuilder.h" +#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/TUSummaryExtractor.h" +#include "llvm/Support/Error.h" +#include <memory> + +namespace clang::ssaf { +class UnsafeBufferUsageTUSummaryExtractor : public TUSummaryExtractor { +public: + UnsafeBufferUsageTUSummaryExtractor(TUSummaryBuilder &Builder) + : TUSummaryExtractor(Builder) {} + + static EntityPointerLevel buildEntityPointerLevel(EntityId Entity, + unsigned PointerLevel) { + return {Entity, PointerLevel}; + } + + EntityId addEntity(EntityName EN) { return SummaryBuilder.addEntity(EN); } + + std::unique_ptr<UnsafeBufferUsageEntitySummary> + extractEntitySummary(const Decl *Contributor, ASTContext &Ctx, + llvm::Error &Error); + + void HandleTranslationUnit(ASTContext &Ctx) override; +}; +} // namespace clang::ssaf + +#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analyses/UnsafeBufferUsage/UnsafeBufferUsageBuilder.h b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analyses/UnsafeBufferUsage/UnsafeBufferUsageBuilder.h deleted file mode 100644 index db6c097510a57..0000000000000 --- a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analyses/UnsafeBufferUsage/UnsafeBufferUsageBuilder.h +++ /dev/null @@ -1,32 +0,0 @@ -//===- UnsafeBufferUsageBuilder.h -------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H -#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H - -#include "clang/ScalableStaticAnalysisFramework/Core/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h" -#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/TUSummaryBuilder.h" -#include <memory> - -namespace clang::ssaf { -class UnsafeBufferUsageTUSummaryBuilder : public TUSummaryBuilder { -public: - static EntityPointerLevel buildEntityPointerLevel(EntityId Entity, - unsigned PointerLevel) { - return {Entity, PointerLevel}; - } - - static std::unique_ptr<UnsafeBufferUsageEntitySummary> - buildUnsafeBufferUsageEntitySummary(EntityPointerLevelSet &&UnsafeBuffers) { - return std::make_unique<UnsafeBufferUsageEntitySummary>( - UnsafeBufferUsageEntitySummary(std::move(UnsafeBuffers))); - } -}; -} // namespace clang::ssaf - -#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h b/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h index 5f201487ca1fe..e0a394da1a921 100644 --- a/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h +++ b/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h @@ -25,4 +25,8 @@ extern volatile int SSAFJSONFormatAnchorSource; [[maybe_unused]] static int SSAFJSONFormatAnchorDestination = SSAFJSONFormatAnchorSource; +extern volatile int UnsafeBufferUsageSSAFJSONFormatAnchorSource; +[[maybe_unused]] static int UnsafeBufferUsageSSAFJSONFormatAnchorDestination = + UnsafeBufferUsageSSAFJSONFormatAnchorSource; + #endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_SSAFBUILTINFORCELINKER_H diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp index 133e39b8fac2b..5a9241acbee36 100644 --- a/clang/lib/Analysis/UnsafeBufferUsage.cpp +++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp @@ -28,6 +28,7 @@ #include "clang/Lex/Preprocessor.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -36,6 +37,7 @@ #include <queue> #include <set> #include <sstream> +#include <vector> using namespace clang; @@ -2942,7 +2944,37 @@ template <typename NodeTy> struct CompareNode { } }; -std::set<const Expr *> clang::findUnsafePointers(const FunctionDecl *FD) { +// Populate `Stmts` with the body/initializer Stmt of `D`, if `D` is one of the +// followings: +// VarDecl +// FieldDecl +// FunctionDecl +// BlockDecl +// ObjCMethodDecl +static void populateStmtsForFindingGadgets(SmallVector<const Stmt *> &Stmts, + const Decl *D) { + auto AddStmt = [&Stmts](const Stmt *S) { + if (S) + Stmts.push_back(S); + }; + if (const auto *FD = dyn_cast<FunctionDecl>(D)) { + AddStmt(FD->getBody()); + for (const auto *PD : FD->parameters()) + AddStmt(PD->getDefaultArg()); + if (const auto *CtorD = dyn_cast<CXXConstructorDecl>(FD)) + llvm::append_range( + Stmts, llvm::map_range(CtorD->inits(), + std::mem_fn(&CXXCtorInitializer::getInit))); + } else if (isa<BlockDecl>(D) || isa<ObjCMethodDecl>(D)) { + AddStmt(D->getBody()); + } else if (const auto *VD = dyn_cast<VarDecl>(D)) { + AddStmt(VD->getInit()); // FIXME: default arg for ParmVarDecl? + } else if (const auto *FD = dyn_cast<FieldDecl>(D)) { + AddStmt(FD->getInClassInitializer()); + } +} + +std::set<const Expr *> clang::findUnsafePointers(const Decl *D) { class MockReporter : public UnsafeBufferUsageHandler { public: MockReporter() {} @@ -2981,9 +3013,13 @@ std::set<const Expr *> clang::findUnsafePointers(const FunctionDecl *FD) { WarningGadgetList WarningGadgets; DeclUseTracker Tracker; MockReporter IgnoreHandler; + ASTContext &Ctx = D->getASTContext(); + SmallVector<const Stmt *> Stmts; - findGadgets(FD->getBody(), FD->getASTContext(), IgnoreHandler, false, - FixableGadgets, WarningGadgets, Tracker); + populateStmtsForFindingGadgets(Stmts, D); + for (auto *Stmt : Stmts) + findGadgets(Stmt, Ctx, IgnoreHandler, false, FixableGadgets, WarningGadgets, + Tracker); std::set<const Expr *> Result; for (auto &G : WarningGadgets) { @@ -4673,9 +4709,6 @@ void clang::checkUnsafeBufferUsage(const Decl *D, #endif assert(D); - - SmallVector<Stmt *> Stmts; - if (const auto *FD = dyn_cast<FunctionDecl>(D)) { // Consteval functions are free of UB by the spec, so we don't need to // visit them or produce diagnostics. @@ -4697,24 +4730,18 @@ void clang::checkUnsafeBufferUsage(const Decl *D, break; } } + } - Stmts.push_back(FD->getBody()); + SmallVector<const Stmt *> Stmts; - if (const auto *ID = dyn_cast<CXXConstructorDecl>(D)) { - for (const CXXCtorInitializer *CI : ID->inits()) { - Stmts.push_back(CI->getInit()); - } - } - } else if (isa<BlockDecl>(D) || isa<ObjCMethodDecl>(D)) { - Stmts.push_back(D->getBody()); - } + populateStmtsForFindingGadgets(Stmts, D); assert(!Stmts.empty()); FixableGadgetList FixableGadgets; WarningGadgetList WarningGadgets; DeclUseTracker Tracker; - for (Stmt *S : Stmts) { + for (const Stmt *S : Stmts) { findGadgets(S, D->getASTContext(), Handler, EmitSuggestions, FixableGadgets, WarningGadgets, Tracker); } diff --git a/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt b/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt new file mode 100644 index 0000000000000..c85fa044c1e9f --- /dev/null +++ b/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt @@ -0,0 +1,16 @@ +set(LLVM_LINK_COMPONENTS + Support + ) + +add_clang_library(clangScalableStaticAnalysisFrameworkAnalyses + UnsafeBufferUsage/UnsafeBufferUsage.cpp + UnsafeBufferUsage/UnsafeBufferUsageExtractor.cpp + + LINK_LIBS + clangAST + clangAnalysis + clangBasic + clangScalableStaticAnalysisFrameworkCore + + DEPENDS + ) diff --git a/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp b/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp new file mode 100644 index 0000000000000..44eaa20c74236 --- /dev/null +++ b/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp @@ -0,0 +1,89 @@ +//===---------- UnsafeBufferUsage.cpp -------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h" +#include "clang/ScalableStaticAnalysisFramework/SSAFForceLinker.h" // IWYU pragma: keep + +namespace { +constexpr const char *const UnsafeBuffersKey = "UnsafeBuffers"; +} // namespace + +namespace clang::ssaf { +using Object = llvm::json::Object; +using Array = llvm::json::Array; +using Value = llvm::json::Value; + +llvm::json::Object UnsafeBufferUsageEntitySummary::jsonSerializeFn( + const EntitySummary &ES, JSONFormat::EntityIdToJSONFn EntityId2JSON) { + // Writes a EntityPointerLevel as + // Array { + // Object { + // "@" : [entity-id] + // }, + // [pointer-level] + // } + Array UnsafeBuffersData; + + for (const auto &EPL : + static_cast<const UnsafeBufferUsageEntitySummary &>(ES).UnsafeBuffers) + UnsafeBuffersData.push_back( + Value(Array{// EntityId: + Value(EntityId2JSON(EPL.getEntity())), + // PointerLevel: + Value(EPL.getPointerLevel())})); + + Object Data; + + Data[UnsafeBuffersKey] = Value(std::move(UnsafeBuffersData)); + return Data; +} + +llvm::Expected<std::unique_ptr<EntitySummary>> +UnsafeBufferUsageEntitySummary::jsonDeserializeFn( + const llvm::json::Object &Data, EntityIdTable &, + JSONFormat::EntityIdFromJSONFn EntityIdFromJSON) { + const Array *UnsafeBuffersData = Data.getArray(UnsafeBuffersKey); + constexpr const char *const ErrMsg = "unrecognized UnsafeBufferUsageEntitySummary data"; + + if (!UnsafeBuffersData) + return llvm::createStringError(ErrMsg); + + EntityPointerLevelSet UnsafeBuffers; + + for (auto &EltData : *UnsafeBuffersData) { + const Array *EltDataAsArr = EltData.getAsArray(); + + if (!EltDataAsArr || EltDataAsArr->size() != 2) + return llvm::createStringError(ErrMsg); + + const Object *IdData = (*EltDataAsArr)[0].getAsObject(); + std::optional<uint64_t> PtrLvData = (*EltDataAsArr)[1].getAsInteger(); + + if (!IdData || !PtrLvData) + return llvm::createStringError(ErrMsg); + + llvm::Expected<EntityId> Id = EntityIdFromJSON(*IdData); + + if (!Id) + return Id.takeError(); + UnsafeBuffers.insert(EntityPointerLevel(Id.get(), *PtrLvData)); + } + return std::make_unique<UnsafeBufferUsageEntitySummary>( + UnsafeBufferUsageEntitySummary(std::move(UnsafeBuffers))); +} + +static llvm::Registry<JSONFormat::FormatInfo>::Add< + UnsafeBufferUsageJSONFormatInfo> + RegisterUnsafeBufferUsageJSONFormatInfo( + "UnsafeBufferUsage", + "JSON Format info for UnsafeBufferUsageEntitySummary"); + +} // namespace clang::ssaf + +// NOLINTNEXTLINE(misc-use-internal-linkage) +volatile int UnsafeBufferUsageSSAFJSONFormatAnchorSource = 0; diff --git a/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/Unsaf... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/187156 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
