18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/iterator_range.h"
20#include "llvm/Support/Error.h"
29 return !Ty.
isNull() && !Ty->isFunctionPointerType() &&
30 (Ty->isPointerType() || Ty->isArrayType());
33constexpr inline auto buildEntityPointerLevel =
55class EntityPointerLevelTranslator
57 Expected<EntityPointerLevelSet>> {
58 friend class StmtVisitorBase;
61 llvm::Error fallback(
const Stmt *E) {
62 return llvm::createStringError(
63 "unsupported expression kind for translation to "
64 "EntityPointerLevel: %s",
68 static EntityPointerLevel incrementPointerLevel(
const EntityPointerLevel &E) {
69 return buildEntityPointerLevel(E.getEntity(), E.getPointerLevel() + 1);
72 static EntityPointerLevel decrementPointerLevel(
const EntityPointerLevel &E) {
73 assert(E.getPointerLevel() > 0);
74 return buildEntityPointerLevel(E.getEntity(), E.getPointerLevel() - 1);
77 EntityPointerLevel createEntityPointerLevelFor(
const EntityName &Name) {
78 return buildEntityPointerLevel(Extractor.addEntity(Name), 1);
83 Expected<EntityPointerLevelSet> translateDereferencePointer(
const Expr *Ptr) {
86 Expected<EntityPointerLevelSet> SubResult = Visit(Ptr);
88 return SubResult.takeError();
90 auto Incremented = llvm::map_range(*SubResult, incrementPointerLevel);
94 UnsafeBufferUsageTUSummaryExtractor &Extractor;
97 EntityPointerLevelTranslator(UnsafeBufferUsageTUSummaryExtractor &Extractor)
98 : Extractor(Extractor) {}
100 Expected<EntityPointerLevelSet> translate(
const Expr *E) {
return Visit(E); }
103 Expected<EntityPointerLevelSet> VisitStmt(
const Stmt *E) {
112 Expected<EntityPointerLevelSet> VisitBinaryOperator(
const BinaryOperator *E) {
116 return Visit(E->
getLHS());
117 return Visit(E->
getRHS());
119 case clang::BO_AddAssign:
120 case clang::BO_SubAssign:
121 case clang::BO_Assign:
122 return Visit(E->
getLHS());
123 case clang::BO_Comma:
124 return Visit(E->
getRHS());
135 Expected<EntityPointerLevelSet> VisitUnaryOperator(
const UnaryOperator *E) {
137 case clang::UO_PostInc:
138 case clang::UO_PostDec:
139 case clang::UO_PreInc:
140 case clang::UO_PreDec:
142 case clang::UO_AddrOf: {
143 Expected<EntityPointerLevelSet> SubResult = Visit(E->
getSubExpr());
145 return SubResult.takeError();
147 auto Decremented = llvm::map_range(*SubResult, decrementPointerLevel);
150 case clang::UO_Deref:
151 return translateDereferencePointer(E->
getSubExpr());
159 Expected<EntityPointerLevelSet> VisitCastExpr(
const CastExpr *E) {
167 Expected<EntityPointerLevelSet> VisitCallExpr(
const CallExpr *E) {
171 createEntityPointerLevelFor(*FDEntityName)};
176 Expected<EntityPointerLevelSet>
177 VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
178 return translateDereferencePointer(E->
getBase());
182 Expected<EntityPointerLevelSet>
183 VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
184 Expected<EntityPointerLevelSet> ReT = Visit(E->
getTrueExpr());
185 Expected<EntityPointerLevelSet> ReF = Visit(E->
getFalseExpr());
188 ReT->insert(ReF->begin(), ReF->end());
192 return llvm::joinErrors(ReT.takeError(), ReF.takeError());
194 return ReF.takeError();
195 return ReT.takeError();
198 Expected<EntityPointerLevelSet> VisitParenExpr(
const ParenExpr *E) {
205 Expected<EntityPointerLevelSet> VisitStringLiteral(
const StringLiteral *E) {
210 Expected<EntityPointerLevelSet> VisitDeclRefExpr(
const DeclRefExpr *E) {
213 return llvm::createStringError(
214 "failed to create entity name from the Decl of " +
219 Expected<EntityPointerLevelSet> VisitMemberExpr(
const MemberExpr *E) {
222 return llvm::createStringError(
223 "failed to create entity name from the MemberDecl of " +
227 Expected<EntityPointerLevelSet>
228 VisitOpaqueValueExpr(
const OpaqueValueExpr *S) {
234buildEntityPointerLevels(std::set<const Expr *> &&UnsafePointers,
237 EntityPointerLevelTranslator Translator{Extractor};
238 llvm::Error AllErrors = llvm::ErrorSuccess();
240 for (
const Expr *Ptr : UnsafePointers) {
246 auto FilteredTranslation = llvm::make_filter_range(
247 *Translation, [](
const EntityPointerLevel &E) ->
bool {
248 return E.getPointerLevel() > 0;
250 Result.insert(FilteredTranslation.begin(), FilteredTranslation.end());
253 AllErrors = llvm::joinErrors(std::move(AllErrors), Translation.takeError());
261std::unique_ptr<UnsafeBufferUsageEntitySummary>
266 if (
const auto *FD = dyn_cast<FunctionDecl>(Contributor)) {
271 return std::make_unique<UnsafeBufferUsageEntitySummary>(
273 Error = EPLs.takeError();
Defines the clang::ASTContext interface.
std::set< EntityPointerLevel, EntityPointerLevel::Comparator > EntityPointerLevelSet
static bool hasPointerType(const Expr &E)
An UnsafeBufferUsageEntitySummary is an immutable set of unsafe buffers, in the form of EntityPointer...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
DeclarationNameInfo getNameInfo() const
Decl - This represents one declaration (or definition), e.g.
This represents one expression.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
const Expr * getSubExpr() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const char * getStmtClassName() const
Expr * getSubExpr() const
std::optional< EntityName > getEntityNameForReturn(const FunctionDecl *FD)
Maps return entity of a function to an EntityName.
std::optional< EntityName > getEntityName(const Decl *D)
Maps a declaration to an EntityName.
The JSON file list parser is used to communicate input to InstallAPI.
std::set< const Expr * > findUnsafePointers(const FunctionDecl *FD)
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.