File tree Expand file tree Collapse file tree 4 files changed +56
-5
lines changed
warn-unsafe-buffer-usage-debug-unclaimed Expand file tree Collapse file tree 4 files changed +56
-5
lines changed Original file line number Diff line number Diff line change @@ -1319,6 +1319,7 @@ static bool isSupportedVariable(const DeclRefExpr &Node) {
13191319 return D != nullptr && isa<VarDecl>(D);
13201320}
13211321
1322+ // Returns true for RecordDecl of type std::unique_ptr<T[]>
13221323static bool isUniquePtrArray (const CXXRecordDecl *RecordDecl) {
13231324 if (!RecordDecl || !RecordDecl->isInStdNamespace () ||
13241325 RecordDecl->getNameAsString () != " unique_ptr" )
@@ -1343,6 +1344,7 @@ static bool isUniquePtrArray(const CXXRecordDecl *RecordDecl) {
13431344}
13441345
13451346class UniquePtrArrayAccessGadget : public WarningGadget {
1347+ private:
13461348 static constexpr const char *const AccessorTag = " unique_ptr_array_access" ;
13471349 const CXXOperatorCallExpr *AccessorExpr;
13481350
@@ -1374,13 +1376,21 @@ class UniquePtrArrayAccessGadget : public WarningGadget {
13741376 if (!Method)
13751377 return false ;
13761378
1377- if (Method->getNameAsString () != " operator[] " )
1379+ if (Method->getOverloadedOperator () != OO_Subscript )
13781380 return false ;
13791381
13801382 const CXXRecordDecl *RecordDecl = Method->getParent ();
13811383 if (!isUniquePtrArray (RecordDecl))
13821384 return false ;
13831385
1386+ const Expr *IndexExpr = OpCall->getArg (1 );
1387+ llvm::APSInt IndexValue;
1388+
1389+ // Allow [0]
1390+ if (IndexExpr->EvaluateAsInt (IndexValue, Ctx) && IndexValue.isZero ()) {
1391+ return false ;
1392+ }
1393+
13841394 Result.addNode (AccessorTag, DynTypedNode::create (*OpCall));
13851395 return true ;
13861396 }
Original file line number Diff line number Diff line change @@ -2613,10 +2613,8 @@ class UnsafeBufferUsageReporter : public UnsafeBufferUsageHandler {
26132613 std::string Message;
26142614
26152615 Loc = Node.get <Stmt>()->getBeginLoc ();
2616- Message = " Direct operator[] access on std::unique_ptr<T[]> is unsafe "
2617- " (no bounds check)." ;
26182616 S.Diag (Loc, diag::warn_unsafe_buffer_usage_unique_ptr_array_access)
2619- << Message << Node.getSourceRange ();
2617+ << Node.getSourceRange ();
26202618 }
26212619
26222620 bool isSafeBufferOptOut (const SourceLocation &Loc) const override {
Original file line number Diff line number Diff line change @@ -42,7 +42,7 @@ template <class T> class unique_ptr {
4242
4343void basic_unique_ptr () {
4444 std::unique_ptr<int []> p1;
45- p1[0 ]; // expected-warning{{direct access using operator[] on std::unique_ptr<T[]> is unsafe due to lack of bounds checking}}
45+ p1[1 ]; // expected-warning{{direct access using operator[] on std::unique_ptr<T[]> is unsafe due to lack of bounds checking}}
4646}
4747
4848// CHECK: Root # 1
Original file line number Diff line number Diff line change 1+ // RUN: %clang_cc1 -Wno-unused-value -Wunsafe-buffer-usage -fsafe-buffer-usage-suggestions -std=c++20 -verify=expected %s
2+
3+ // This debugging facility is only available in debug builds.
4+ //
5+ // REQUIRES: asserts
6+
7+ namespace std {
8+ inline namespace __1 {
9+ template <class T > class unique_ptr {
10+ public:
11+ T &operator [](long long i) const ;
12+ };
13+ } // namespace __1
14+ } // namespace std
15+
16+ void basic_unique_ptr () {
17+ std::unique_ptr<int []> p1;
18+ int i = 2 ;
19+
20+ p1[0 ]; // This is allowed
21+
22+ p1[1 ]; // expected-warning{{direct access using operator[] on std::unique_ptr<T[]> is unsafe due to lack of bounds checking}}
23+
24+ p1[i]; // expected-warning{{direct access using operator[] on std::unique_ptr<T[]> is unsafe due to lack of bounds checking}}
25+
26+ p1[i + 5 ]; // expected-warning{{direct access using operator[] on std::unique_ptr<T[]> is unsafe due to lack of bounds checking}}
27+ }
28+
29+ // CHECK: Root # 1
30+ // CHECK: |- DeclRefExpr # 4
31+ // CHECK: |-- UnaryOperator(++) # 1
32+ // CHECK: |--- CompoundStmt # 1
33+ // CHECK: |-- ImplicitCastExpr(LValueToRValue) # 1
34+ // CHECK: |--- BinaryOperator(+) # 1
35+ // CHECK: |---- ParenExpr # 1
36+ // CHECK: |----- BinaryOperator(+) # 1
37+ // CHECK: |------ ParenExpr # 1
38+ // CHECK: |------- UnaryOperator(*) # 1
39+ // CHECK: |-------- CompoundStmt # 1
40+ // CHECK: |-- BinaryOperator(-=) # 1
41+ // CHECK: |--- CompoundStmt # 1
42+ // CHECK: |-- UnaryOperator(--) # 1
43+ // CHECK: |--- CompoundStmt # 1
You can’t perform that action at this time.
0 commit comments