Skip to content

Commit 11fc596

Browse files
committed
Update UnsafeBufferUsage.cpp
1 parent 980a75e commit 11fc596

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "clang/AST/Attr.h"
1414
#include "clang/AST/Decl.h"
1515
#include "clang/AST/DeclCXX.h"
16+
#include "clang/AST/DeclTemplate.h"
1617
#include "clang/AST/DynamicRecursiveASTVisitor.h"
1718
#include "clang/AST/Expr.h"
1819
#include "clang/AST/FormatString.h"
@@ -1318,6 +1319,105 @@ static bool isSupportedVariable(const DeclRefExpr &Node) {
13181319
return D != nullptr && isa<VarDecl>(D);
13191320
}
13201321

1322+
static bool isUniquePtrArray(const CXXRecordDecl *RecordDecl) {
1323+
if (!RecordDecl || !RecordDecl->isInStdNamespace() ||
1324+
RecordDecl->getNameAsString() != "unique_ptr") {
1325+
return false;
1326+
}
1327+
1328+
const ClassTemplateSpecializationDecl *class_template_specialization_decl =
1329+
dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
1330+
if (!class_template_specialization_decl) {
1331+
return false;
1332+
}
1333+
1334+
const TemplateArgumentList &template_args =
1335+
class_template_specialization_decl->getTemplateArgs();
1336+
1337+
if (template_args.size() == 0) {
1338+
return false;
1339+
}
1340+
1341+
const TemplateArgument &first_arg = template_args[0];
1342+
1343+
if (first_arg.getKind() != TemplateArgument::Type) {
1344+
return false;
1345+
}
1346+
1347+
QualType referred_type = first_arg.getAsType();
1348+
1349+
if (referred_type->isArrayType()) {
1350+
return true;
1351+
}
1352+
1353+
return false;
1354+
}
1355+
1356+
class UniquePtrArrayAccessGadget : public WarningGadget {
1357+
static constexpr const char *const AccessorTag = "unique_ptr_array_access";
1358+
const CXXOperatorCallExpr *TheAccessorExpr;
1359+
1360+
public:
1361+
UniquePtrArrayAccessGadget(const MatchResult &Result)
1362+
: WarningGadget(Kind::UniquePtrArrayAccess),
1363+
TheAccessorExpr(Result.getNodeAs<CXXOperatorCallExpr>(AccessorTag)) {
1364+
assert(TheAccessorExpr &&
1365+
"UniquePtrArrayAccessGadget requires a matched CXXOperatorCallExpr");
1366+
}
1367+
1368+
static bool classof(const Gadget *G) {
1369+
return G->getKind() == Kind::UniquePtrArrayAccess;
1370+
}
1371+
1372+
static bool matches(const Stmt *S, const ASTContext &Ctx,
1373+
MatchResult &Result) {
1374+
1375+
const CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(S);
1376+
if (!OpCall || OpCall->getOperator() != OO_Subscript) {
1377+
return false;
1378+
}
1379+
1380+
const Expr *Callee = OpCall->getCallee()->IgnoreParenImpCasts();
1381+
if (!Callee) {
1382+
return false;
1383+
}
1384+
1385+
const CXXMethodDecl *Method =
1386+
dyn_cast_or_null<CXXMethodDecl>(OpCall->getDirectCallee());
1387+
if (!Method) {
1388+
return false;
1389+
}
1390+
1391+
if (Method->getNameAsString() != "operator[]") {
1392+
return false;
1393+
}
1394+
1395+
const CXXRecordDecl *RecordDecl = Method->getParent();
1396+
if (!isUniquePtrArray(RecordDecl)) {
1397+
return false;
1398+
}
1399+
1400+
Result.addNode(AccessorTag, DynTypedNode::create(*OpCall));
1401+
return true;
1402+
}
1403+
void handleUnsafeOperation(UnsafeBufferUsageHandler &Handler,
1404+
bool IsRelatedToDecl,
1405+
ASTContext &Ctx) const override {
1406+
Handler.handleUnsafeUniquePtrArrayAccess(
1407+
DynTypedNode::create(*TheAccessorExpr), IsRelatedToDecl, Ctx);
1408+
}
1409+
1410+
SourceLocation getSourceLoc() const override {
1411+
if (TheAccessorExpr) {
1412+
return TheAccessorExpr->getOperatorLoc();
1413+
}
1414+
return SourceLocation();
1415+
}
1416+
1417+
DeclUseList getClaimedVarUseSites() const override { return {}; }
1418+
SmallVector<const Expr *, 1> getUnsafePtrs() const override { return {}; }
1419+
};
1420+
13211421
using FixableGadgetList = std::vector<std::unique_ptr<FixableGadget>>;
13221422
using WarningGadgetList = std::vector<std::unique_ptr<WarningGadget>>;
13231423

@@ -2647,6 +2747,10 @@ std::set<const Expr *> clang::findUnsafePointers(const FunctionDecl *FD) {
26472747
}
26482748
};
26492749

2750+
void handleUnsafeUniquePtrArrayAccess(const DynTypedNode &Node,
2751+
bool IsRelatedToDecl,
2752+
ASTContext &Ctx) override {}
2753+
26502754
FixableGadgetList FixableGadgets;
26512755
WarningGadgetList WarningGadgets;
26522756
DeclUseTracker Tracker;

0 commit comments

Comments
 (0)