Skip to content

Commit a3c9d88

Browse files
committed
[analyzer] MIGChecker: Add support for more deallocator APIs.
Differential Revision: https://reviews.llvm.org/D59914 llvm-svn: 357335
1 parent 5dc6a73 commit a3c9d88

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,33 @@ class MIGChecker : public Checker<check::PostCall, check::PreStmt<ReturnStmt>,
5454
CALL(3, 1, "mach_vm_deallocate"),
5555
CALL(2, 0, "mig_deallocate"),
5656
CALL(2, 1, "mach_port_deallocate"),
57+
CALL(1, 0, "device_deallocate"),
58+
CALL(1, 0, "iokit_remove_connect_reference"),
59+
CALL(1, 0, "iokit_remove_reference"),
60+
CALL(1, 0, "iokit_release_port"),
61+
CALL(1, 0, "ipc_port_release"),
62+
CALL(1, 0, "ipc_port_release_sonce"),
63+
CALL(1, 0, "ipc_voucher_attr_control_release"),
64+
CALL(1, 0, "ipc_voucher_release"),
65+
CALL(1, 0, "lock_set_dereference"),
66+
CALL(1, 0, "memory_object_control_deallocate"),
67+
CALL(1, 0, "pset_deallocate"),
68+
CALL(1, 0, "semaphore_dereference"),
69+
CALL(1, 0, "space_deallocate"),
70+
CALL(1, 0, "space_inspect_deallocate"),
71+
CALL(1, 0, "task_deallocate"),
72+
CALL(1, 0, "task_inspect_deallocate"),
73+
CALL(1, 0, "task_name_deallocate"),
74+
CALL(1, 0, "thread_deallocate"),
75+
CALL(1, 0, "thread_inspect_deallocate"),
76+
CALL(1, 0, "upl_deallocate"),
77+
CALL(1, 0, "vm_map_deallocate"),
5778
// E.g., if the checker sees a method 'releaseAsyncReference64()' that is
5879
// defined on class 'IOUserClient' that takes exactly 1 argument, it knows
5980
// that the argument is going to be consumed in the sense of the MIG
6081
// consume-on-success convention.
6182
CALL(1, 0, "IOUserClient", "releaseAsyncReference64"),
83+
CALL(1, 0, "IOUserClient", "releaseNotificationPort"),
6284
#undef CALL
6385
};
6486

clang/test/Analysis/mig.mm

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@
1515
typedef unsigned vm_size_t;
1616
typedef void *ipc_space_t;
1717
typedef unsigned long io_user_reference_t;
18+
typedef struct ipc_port *ipc_port_t;
19+
typedef unsigned mach_port_t;
20+
typedef uint32_t UInt32;
1821

1922
kern_return_t vm_deallocate(mach_port_name_t, vm_address_t, vm_size_t);
2023
kern_return_t mach_vm_deallocate(mach_port_name_t, vm_address_t, vm_size_t);
2124
void mig_deallocate(vm_address_t, vm_size_t);
2225
kern_return_t mach_port_deallocate(ipc_space_t, mach_port_name_t);
26+
void ipc_port_release(ipc_port_t);
2327

2428
#define MIG_SERVER_ROUTINE __attribute__((mig_server_routine))
2529

@@ -44,12 +48,17 @@
4448
class IOUserClient {
4549
public:
4650
static IOReturn releaseAsyncReference64(OSAsyncReference64);
51+
static IOReturn releaseNotificationPort(mach_port_t port);
4752

4853
MIG_SERVER_ROUTINE
49-
virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments *arguments,
50-
IOExternalMethodDispatch *dispatch = 0, OSObject *target = 0, void *reference = 0);
51-
};
54+
virtual IOReturn externalMethod(
55+
uint32_t selector, IOExternalMethodArguments *arguments,
56+
IOExternalMethodDispatch *dispatch = 0, OSObject *target = 0,
57+
void *reference = 0);
5258

59+
MIG_SERVER_ROUTINE
60+
virtual IOReturn registerNotificationPort(mach_port_t, UInt32, UInt32);
61+
};
5362

5463
// Tests.
5564

@@ -182,6 +191,13 @@ kern_return_t test_mig_deallocate(vm_address_t address, vm_size_t size) {
182191
// expected-note@-1{{MIG callback fails with error after deallocating argument value}}
183192
}
184193

194+
MIG_SERVER_ROUTINE
195+
kern_return_t test_ipc_port_release(ipc_port_t port) {
196+
ipc_port_release(port); // expected-note{{Value passed through parameter 'port' is deallocated}}
197+
return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value}}
198+
// expected-note@-1{{MIG callback fails with error after deallocating argument value}}
199+
}
200+
185201
// Let's try the C++11 attribute spelling syntax as well.
186202
[[clang::mig_server_routine]]
187203
IOReturn test_releaseAsyncReference64(IOExternalMethodArguments *arguments) {
@@ -206,4 +222,10 @@ IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments *arguments,
206222
return kIOReturnError; // expected-warning{{MIG callback fails with error after deallocating argument value}}
207223
// expected-note@-1{{MIG callback fails with error after deallocating argument value}}
208224
}
225+
226+
IOReturn registerNotificationPort(mach_port_t port, UInt32 x, UInt32 y) {
227+
releaseNotificationPort(port); // expected-note{{Value passed through parameter 'port' is deallocated}}
228+
return kIOReturnError; // expected-warning{{MIG callback fails with error after deallocating argument value}}
229+
// expected-note@-1{{MIG callback fails with error after deallocating argument value}}
230+
}
209231
};

0 commit comments

Comments
 (0)