llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Ziqing Luo (ziqingluo-90) <details> <summary>Changes</summary> Reverts llvm/llvm-project#<!-- -->191331 A set of bots are broken. --- Patch is 32.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/191481.diff 8 Files Affected: - (removed) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h (-99) - (modified) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h (+67-1) - (modified) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h (+5) - (modified) clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt (-1) - (removed) clang/lib/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.cpp (-244) - (modified) clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp (+4) - (modified) clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.cpp (+213-7) - (modified) clang/unittests/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageTest.cpp (+3-1) ``````````diff diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h deleted file mode 100644 index 52caa52e1120d..0000000000000 --- a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h +++ /dev/null @@ -1,99 +0,0 @@ -//===- EntityPointerLevel.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_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVEL_H -#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVEL_H - -#include "clang/AST/Expr.h" -#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h" -#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityName.h" -#include <set> - -namespace clang::ssaf { - -/// An EntityPointerLevel represents a level of the declared pointer/array -/// type of an entity. In the fully-expanded spelling of the declared type, a -/// EntityPointerLevel is associated with a '*' (or a '[]`) in that declaration. -/// -/// For example, for 'int *p[10];', there are two EntityPointerLevels. One -/// is associated with 'int *[10]' of 'p' and the other is associated with 'int -/// *' 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'). -/// -/// For the same example 'int *p[10];', the EntityPointerLevels below are valid: -/// - '(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 EntityPointerLevelTranslator; - friend EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned); - - EntityPointerLevel(EntityId Entity, unsigned PointerLevel) - : Entity(Entity), PointerLevel(PointerLevel) {} - -public: - EntityId getEntity() const { return Entity; } - unsigned getPointerLevel() const { return PointerLevel; } - - bool operator==(const EntityPointerLevel &Other) const { - return std::tie(Entity, PointerLevel) == - std::tie(Other.Entity, Other.PointerLevel); - } - - bool operator!=(const EntityPointerLevel &Other) const { - return !(*this == Other); - } - - bool operator<(const EntityPointerLevel &Other) const { - return std::tie(Entity, PointerLevel) < - std::tie(Other.Entity, Other.PointerLevel); - } - - /// Compares `EntityPointerLevel`s; additionally, partially compares - /// `EntityPointerLevel` with `EntityId`. - struct Comparator { - using is_transparent = void; - bool operator()(const EntityPointerLevel &L, - const EntityPointerLevel &R) const { - return L < R; - } - bool operator()(const EntityId &L, const EntityPointerLevel &R) const { - return L < R.getEntity(); - } - bool operator()(const EntityPointerLevel &L, const EntityId &R) const { - return L.getEntity() < R; - } - }; -}; - -using EntityPointerLevelSet = - std::set<EntityPointerLevel, EntityPointerLevel::Comparator>; - -/// Translate a pointer/array type expression 'E' to a (set of) -/// EntityPointerLevel(s) associated with the declared type of the base address -/// of `E`. If the base address of `E` is not associated with an entity, the -/// translation result is an empty set. -/// -/// \param E the pointer expression to be translated -/// \param Ctx the AST context of `E` -/// \param AddEntity the callback provided by the caller to convert EntityNames -/// to EntityIds. -llvm::Expected<EntityPointerLevelSet> -translateEntityPointerLevel(const Expr *E, ASTContext &Ctx, - std::function<EntityId(EntityName EN)> AddEntity); - -EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned); -} // namespace clang::ssaf -#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVEL_H diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h index 250bad5b72f75..4e217c2eb87ef 100644 --- a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h +++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGE_H #define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGE_H -#include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h" +#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h" #include "clang/ScalableStaticAnalysisFramework/Core/Model/SummaryName.h" #include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/EntitySummary.h" #include "llvm/ADT/StringRef.h" @@ -18,6 +18,72 @@ namespace clang::ssaf { +/// An EntityPointerLevel represents a level of the declared pointer/array +/// type of an entity. In the fully-expanded spelling of the declared type, a +/// EntityPointerLevel is associated with a '*' (or a '[]`) in that declaration. +/// +/// For example, for 'int *p[10];', there are two EntityPointerLevels. One +/// is associated with 'int *[10]' of 'p' and the other is associated with 'int +/// *' 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'). +/// +/// For the same example 'int *p[10];', the EntityPointerLevels below are valid: +/// - '(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 UnsafeBufferUsageEntitySummary; + friend class UnsafeBufferUsageTUSummaryExtractor; + friend EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned); + + EntityPointerLevel(EntityId Entity, unsigned PointerLevel) + : Entity(Entity), PointerLevel(PointerLevel) {} + +public: + EntityId getEntity() const { return Entity; } + unsigned getPointerLevel() const { return PointerLevel; } + + bool operator==(const EntityPointerLevel &Other) const { + return std::tie(Entity, PointerLevel) == + std::tie(Other.Entity, Other.PointerLevel); + } + + bool operator!=(const EntityPointerLevel &Other) const { + return !(*this == Other); + } + + bool operator<(const EntityPointerLevel &Other) const { + return std::tie(Entity, PointerLevel) < + std::tie(Other.Entity, Other.PointerLevel); + } + + /// Compares `EntityPointerLevel`s; additionally, partially compares + /// `EntityPointerLevel` with `EntityId`. + struct Comparator { + using is_transparent = void; + bool operator()(const EntityPointerLevel &L, + const EntityPointerLevel &R) const { + return L < R; + } + bool operator()(const EntityId &L, const EntityPointerLevel &R) const { + return L < R.getEntity(); + } + bool operator()(const EntityPointerLevel &L, const EntityId &R) const { + return L.getEntity() < R; + } + }; +}; + +using EntityPointerLevelSet = + std::set<EntityPointerLevel, EntityPointerLevel::Comparator>; + /// An UnsafeBufferUsageEntitySummary is an immutable set of unsafe buffers, in /// the form of EntityPointerLevel. class UnsafeBufferUsageEntitySummary final : public EntitySummary { diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h index 13d4e18b4e81f..765b2c37562ce 100644 --- a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h +++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h @@ -22,6 +22,11 @@ class UnsafeBufferUsageTUSummaryExtractor : public TUSummaryExtractor { 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> diff --git a/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt b/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt index c15ff3b3c42e7..926b610aa8dee 100644 --- a/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt +++ b/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt @@ -5,7 +5,6 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangScalableStaticAnalysisFrameworkAnalyses CallGraph/CallGraphExtractor.cpp CallGraph/CallGraphJSONFormat.cpp - EntityPointerLevel/EntityPointerLevel.cpp UnsafeBufferUsage/UnsafeBufferUsage.cpp UnsafeBufferUsage/UnsafeBufferUsageExtractor.cpp diff --git a/clang/lib/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.cpp b/clang/lib/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.cpp deleted file mode 100644 index 49a135b13877a..0000000000000 --- a/clang/lib/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.cpp +++ /dev/null @@ -1,244 +0,0 @@ -//===- EntityPointerLevel.cpp ----------------------------------*- 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 -// -//===----------------------------------------------------------------------===// - -#include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Decl.h" -#include "clang/AST/StmtVisitor.h" -#include "clang/ScalableStaticAnalysisFramework/Core/ASTEntityMapping.h" -#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityName.h" - -using namespace clang; -using namespace ssaf; - -static bool hasPointerType(const Expr *E) { - auto Ty = E->getType(); - return !Ty.isNull() && !Ty->isFunctionPointerType() && - (Ty->isPointerType() || Ty->isArrayType()); -} - -static llvm::Error makeUnsupportedStmtKindError(const Stmt *Unsupported) { - return llvm::createStringError( - "unsupported expression kind for translation to " - "EntityPointerLevel: %s", - Unsupported->getStmtClassName()); -} - -static llvm::Error makeCreateEntityNameError(const NamedDecl *FailedDecl, - ASTContext &Ctx) { - std::string LocStr = FailedDecl->getSourceRange().getBegin().printToString( - Ctx.getSourceManager()); - return llvm::createStringError( - "failed to create entity name for %s declared at %s", - FailedDecl->getNameAsString().c_str(), LocStr.c_str()); -} - -// Translate a pointer type expression 'E' to a (set of) EntityPointerLevel(s) -// associated with the declared type of the base address of `E`. If the base -// address of `E` is not associated with an entity, the translation result is an -// empty set. -// -// The translation is a process of traversing into the pointer 'E' until its -// base address can be represented by an entity, with the number of dereferences -// tracked by incrementing the pointer level. Naturally, taking address of, as -// the inverse operation of dereference, is tracked by decrementing the pointer -// level. -// -// For example, suppose there are pointers and arrays declared as -// int *ptr, **p1, **p2; -// int arr[10][10]; -// , the translation of expressions involving these base addresses will be: -// Translate(ptr + 5) -> {(ptr, 1)} -// Translate(arr[5]) -> {(arr, 2)} -// Translate(cond ? p1[5] : p2) -> {(p1, 2), (p2, 1)} -// Translate(&arr[5]) -> {(arr, 1)} -class ssaf::EntityPointerLevelTranslator - : ConstStmtVisitor<EntityPointerLevelTranslator, - Expected<EntityPointerLevelSet>> { - friend class StmtVisitorBase; - - // Fallback method for all unsupported expression kind: - llvm::Error fallback(const Stmt *E) { - return makeUnsupportedStmtKindError(E); - } - - static EntityPointerLevel incrementPointerLevel(const EntityPointerLevel &E) { - return EntityPointerLevel(E.getEntity(), E.getPointerLevel() + 1); - } - - static EntityPointerLevel decrementPointerLevel(const EntityPointerLevel &E) { - assert(E.getPointerLevel() > 0); - return EntityPointerLevel(E.getEntity(), E.getPointerLevel() - 1); - } - - EntityPointerLevel createEntityPointerLevelFor(const EntityName &Name) { - return EntityPointerLevel(AddEntity(Name), 1); - } - - // The common helper function for Translate(*base): - // Translate(*base) -> Translate(base) with .pointerLevel + 1 - Expected<EntityPointerLevelSet> translateDereferencePointer(const Expr *Ptr) { - assert(hasPointerType(Ptr)); - - Expected<EntityPointerLevelSet> SubResult = Visit(Ptr); - if (!SubResult) - return SubResult.takeError(); - - auto Incremented = llvm::map_range(*SubResult, incrementPointerLevel); - return EntityPointerLevelSet{Incremented.begin(), Incremented.end()}; - } - - std::function<EntityId(EntityName EN)> AddEntity; - ASTContext &Ctx; - -public: - EntityPointerLevelTranslator(std::function<EntityId(EntityName EN)> AddEntity, - ASTContext &Ctx) - : AddEntity(AddEntity), Ctx(Ctx) {} - - Expected<EntityPointerLevelSet> translate(const Expr *E) { return Visit(E); } - -private: - Expected<EntityPointerLevelSet> VisitStmt(const Stmt *E) { - return fallback(E); - } - - // Translate(base + x) -> Translate(base) - // Translate(x + base) -> Translate(base) - // Translate(base - x) -> Translate(base) - // Translate(base {+=, -=, =} x) -> Translate(base) - // Translate(x, base) -> Translate(base) - Expected<EntityPointerLevelSet> VisitBinaryOperator(const BinaryOperator *E) { - switch (E->getOpcode()) { - case clang::BO_Add: - if (hasPointerType(E->getLHS())) - return Visit(E->getLHS()); - return Visit(E->getRHS()); - case clang::BO_Sub: - case clang::BO_AddAssign: - case clang::BO_SubAssign: - case clang::BO_Assign: - return Visit(E->getLHS()); - case clang::BO_Comma: - return Visit(E->getRHS()); - default: - return fallback(E); - } - } - - // Translate({++, --}base) -> Translate(base) - // Translate(base{++, --}) -> Translate(base) - // Translate(*base) -> Translate(base) with .pointerLevel += 1 - // Translate(&base) -> {}, if Translate(base) is {} - // -> Translate(base) with .pointerLevel -= 1 - Expected<EntityPointerLevelSet> VisitUnaryOperator(const UnaryOperator *E) { - switch (E->getOpcode()) { - case clang::UO_PostInc: - case clang::UO_PostDec: - case clang::UO_PreInc: - case clang::UO_PreDec: - return Visit(E->getSubExpr()); - case clang::UO_AddrOf: { - Expected<EntityPointerLevelSet> SubResult = Visit(E->getSubExpr()); - if (!SubResult) - return SubResult.takeError(); - - auto Decremented = llvm::map_range(*SubResult, decrementPointerLevel); - return EntityPointerLevelSet{Decremented.begin(), Decremented.end()}; - } - case clang::UO_Deref: - return translateDereferencePointer(E->getSubExpr()); - default: - return fallback(E); - } - } - - // Translate((T*)base) -> Translate(p) if p has pointer type - // -> {} otherwise - Expected<EntityPointerLevelSet> VisitCastExpr(const CastExpr *E) { - if (hasPointerType(E->getSubExpr())) - return Visit(E->getSubExpr()); - return EntityPointerLevelSet{}; - } - - // Translate(f(...)) -> {} if it is an indirect call - // -> {(f_return, 1)}, otherwise - Expected<EntityPointerLevelSet> VisitCallExpr(const CallExpr *E) { - if (auto *FD = E->getDirectCallee()) - if (auto FDEntityName = getEntityNameForReturn(FD)) - return EntityPointerLevelSet{ - createEntityPointerLevelFor(*FDEntityName)}; - return EntityPointerLevelSet{}; - } - - // Translate(base[x]) -> Translate(*base) - Expected<EntityPointerLevelSet> - VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { - return translateDereferencePointer(E->getBase()); - } - - // Translate(cond ? base1 : base2) := Translate(base1) U Translate(base2) - Expected<EntityPointerLevelSet> - VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { - Expected<EntityPointerLevelSet> ReT = Visit(E->getTrueExpr()); - Expected<EntityPointerLevelSet> ReF = Visit(E->getFalseExpr()); - - if (ReT && ReF) { - ReT->insert(ReF->begin(), ReF->end()); - return ReT; - } - if (!ReF && !ReT) - return llvm::joinErrors(ReT.takeError(), ReF.takeError()); - if (!ReF) - return ReF.takeError(); - return ReT.takeError(); - } - - Expected<EntityPointerLevelSet> VisitParenExpr(const ParenExpr *E) { - return Visit(E->getSubExpr()); - } - - // Translate("string-literal") -> {} - // Buffer accesses on string literals are unsafe, but string literals are not - // entities so there is no EntityPointerLevel associated with it. - Expected<EntityPointerLevelSet> VisitStringLiteral(const StringLiteral *E) { - return EntityPointerLevelSet{}; - } - - // Translate(DRE) -> {(Decl, 1)} - Expected<EntityPointerLevelSet> VisitDeclRefExpr(const DeclRefExpr *E) { - if (auto EntityName = getEntityName(E->getDecl())) - return EntityPointerLevelSet{createEntityPointerLevelFor(*EntityName)}; - return makeCreateEntityNameError(E->getDecl(), Ctx); - } - - // Translate({., ->}f) -> {(MemberDecl, 1)} - Expected<EntityPointerLevelSet> VisitMemberExpr(const MemberExpr *E) { - if (auto EntityName = getEntityName(E->getMemberDecl())) - return EntityPointerLevelSet{createEntityPointerLevelFor(*EntityName)}; - return makeCreateEntityNameError(E->getMemberDecl(), Ctx); - } - - Expected<EntityPointerLevelSet> - VisitOpaqueValueExpr(const OpaqueValueExpr *S) { - return Visit(S->getSourceExpr()); - } -}; - -Expected<EntityPointerLevelSet> clang::ssaf::translateEntityPointerLevel( - const Expr *E, ASTContext &Ctx, - std::function<EntityId(EntityName EN)> AddEntity) { - EntityPointerLevelTranslator Translator(AddEntity, Ctx); - - return Translator.translate(E); -} - -EntityPointerLevel clang::ssaf::buildEntityPointerLevel(EntityId Id, - unsigned PtrLv) { - return EntityPointerLevel({Id, PtrLv}); -} diff --git a/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp b/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp index 84f3f9cbb3852..d325e8df79c20 100644 --- a/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp +++ b/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp @@ -21,6 +21,10 @@ using Object = llvm::json::Object; static constexpr llvm::StringLiteral SummarySerializationKe... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/191481 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
