Skip to content

Commit cd02bd9

Browse files
pskrgagyuxuanchen1997
authored andcommitted
[clang][analyzer] Support ownership_{returns,takes} attributes (#98941)
Summary: Add support for checking mismatched ownership_returns/ownership_takes attributes. Closes #76861 Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60250804
1 parent 3806550 commit cd02bd9

20 files changed

+414
-222
lines changed

clang/docs/ReleaseNotes.rst

+8
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ Removed Compiler Flags
108108
Attribute Changes in Clang
109109
--------------------------
110110

111+
- Clang now disallows more than one ``__attribute__((ownership_returns(class, idx)))`` with
112+
different class names attached to one function.
113+
111114
Improvements to Clang's diagnostics
112115
-----------------------------------
113116

@@ -217,6 +220,11 @@ Static Analyzer
217220
New features
218221
^^^^^^^^^^^^
219222

223+
- MallocChecker now checks for ``ownership_returns(class, idx)`` and ``ownership_takes(class, idx)``
224+
attributes with class names different from "malloc". Clang static analyzer now reports an error
225+
if class of allocation and deallocation function mismatches.
226+
`Documentation <https://clang.llvm.org/docs/analyzer/checkers.html#unix-mismatcheddeallocator-c-c>`__.
227+
220228
Crash and bug fixes
221229
^^^^^^^^^^^^^^^^^^^
222230

clang/docs/analyzer/checkers/mismatched_deallocator_example.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ void test() {
66

77
// C, C++
88
void __attribute((ownership_returns(malloc))) *user_malloc(size_t);
9+
void __attribute((ownership_takes(malloc, 1))) *user_free(void *);
10+
11+
void __attribute((ownership_returns(malloc1))) *user_malloc1(size_t);
12+
void __attribute((ownership_takes(malloc1, 1))) *user_free1(void *);
913

1014
void test() {
1115
int *p = (int *)user_malloc(sizeof(int));
@@ -24,6 +28,12 @@ void test() {
2428
realloc(p, sizeof(long)); // warn
2529
}
2630

31+
// C, C++
32+
void test() {
33+
int *p = user_malloc(10);
34+
user_free1(p); // warn
35+
}
36+
2737
// C, C++
2838
template <typename T>
2939
struct SimpleSmartPointer {

clang/include/clang/Basic/DiagnosticSemaKinds.td

+4
Original file line numberDiff line numberDiff line change
@@ -3334,6 +3334,10 @@ def err_ownership_returns_index_mismatch : Error<
33343334
"'ownership_returns' attribute index does not match; here it is %0">;
33353335
def note_ownership_returns_index_mismatch : Note<
33363336
"declared with index %0 here">;
3337+
def err_ownership_takes_class_mismatch : Error<
3338+
"'ownership_takes' attribute class does not match; here it is '%0'">;
3339+
def note_ownership_takes_class_mismatch : Note<
3340+
"declared with class '%0' here">;
33373341
def err_format_strftime_third_parameter : Error<
33383342
"strftime format attribute requires 3rd parameter to be 0">;
33393343
def err_format_attribute_not : Error<"format argument not a string type">;

clang/lib/Sema/SemaDeclAttr.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,16 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
15371537
<< Idx.getSourceIndex() << Ex->getSourceRange();
15381538
return;
15391539
}
1540+
} else if (K == OwnershipAttr::Takes &&
1541+
I->getOwnKind() == OwnershipAttr::Takes) {
1542+
if (I->getModule()->getName() != ModuleName) {
1543+
S.Diag(I->getLocation(), diag::err_ownership_takes_class_mismatch)
1544+
<< I->getModule()->getName();
1545+
S.Diag(AL.getLoc(), diag::note_ownership_takes_class_mismatch)
1546+
<< ModuleName << Ex->getSourceRange();
1547+
1548+
return;
1549+
}
15401550
}
15411551
}
15421552
OwnershipArgs.push_back(Idx);

0 commit comments

Comments
 (0)