summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp22
-rw-r--r--clang/test/Analysis/mig.mm28
2 files changed, 47 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp
index 685fd88b165..256599289d4 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp
@@ -54,11 +54,33 @@ class MIGChecker : public Checker<check::PostCall, check::PreStmt<ReturnStmt>,
CALL(3, 1, "mach_vm_deallocate"),
CALL(2, 0, "mig_deallocate"),
CALL(2, 1, "mach_port_deallocate"),
+ CALL(1, 0, "device_deallocate"),
+ CALL(1, 0, "iokit_remove_connect_reference"),
+ CALL(1, 0, "iokit_remove_reference"),
+ CALL(1, 0, "iokit_release_port"),
+ CALL(1, 0, "ipc_port_release"),
+ CALL(1, 0, "ipc_port_release_sonce"),
+ CALL(1, 0, "ipc_voucher_attr_control_release"),
+ CALL(1, 0, "ipc_voucher_release"),
+ CALL(1, 0, "lock_set_dereference"),
+ CALL(1, 0, "memory_object_control_deallocate"),
+ CALL(1, 0, "pset_deallocate"),
+ CALL(1, 0, "semaphore_dereference"),
+ CALL(1, 0, "space_deallocate"),
+ CALL(1, 0, "space_inspect_deallocate"),
+ CALL(1, 0, "task_deallocate"),
+ CALL(1, 0, "task_inspect_deallocate"),
+ CALL(1, 0, "task_name_deallocate"),
+ CALL(1, 0, "thread_deallocate"),
+ CALL(1, 0, "thread_inspect_deallocate"),
+ CALL(1, 0, "upl_deallocate"),
+ CALL(1, 0, "vm_map_deallocate"),
// E.g., if the checker sees a method 'releaseAsyncReference64()' that is
// defined on class 'IOUserClient' that takes exactly 1 argument, it knows
// that the argument is going to be consumed in the sense of the MIG
// consume-on-success convention.
CALL(1, 0, "IOUserClient", "releaseAsyncReference64"),
+ CALL(1, 0, "IOUserClient", "releaseNotificationPort"),
#undef CALL
};
diff --git a/clang/test/Analysis/mig.mm b/clang/test/Analysis/mig.mm
index 59442d39e4a..bc432928ed8 100644
--- a/clang/test/Analysis/mig.mm
+++ b/clang/test/Analysis/mig.mm
@@ -15,11 +15,15 @@ typedef unsigned vm_address_t;
typedef unsigned vm_size_t;
typedef void *ipc_space_t;
typedef unsigned long io_user_reference_t;
+typedef struct ipc_port *ipc_port_t;
+typedef unsigned mach_port_t;
+typedef uint32_t UInt32;
kern_return_t vm_deallocate(mach_port_name_t, vm_address_t, vm_size_t);
kern_return_t mach_vm_deallocate(mach_port_name_t, vm_address_t, vm_size_t);
void mig_deallocate(vm_address_t, vm_size_t);
kern_return_t mach_port_deallocate(ipc_space_t, mach_port_name_t);
+void ipc_port_release(ipc_port_t);
#define MIG_SERVER_ROUTINE __attribute__((mig_server_routine))
@@ -44,12 +48,17 @@ struct IOExternalMethodDispatch {};
class IOUserClient {
public:
static IOReturn releaseAsyncReference64(OSAsyncReference64);
+ static IOReturn releaseNotificationPort(mach_port_t port);
MIG_SERVER_ROUTINE
- virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments *arguments,
- IOExternalMethodDispatch *dispatch = 0, OSObject *target = 0, void *reference = 0);
-};
+ virtual IOReturn externalMethod(
+ uint32_t selector, IOExternalMethodArguments *arguments,
+ IOExternalMethodDispatch *dispatch = 0, OSObject *target = 0,
+ void *reference = 0);
+ MIG_SERVER_ROUTINE
+ virtual IOReturn registerNotificationPort(mach_port_t, UInt32, UInt32);
+};
// Tests.
@@ -182,6 +191,13 @@ kern_return_t test_mig_deallocate(vm_address_t address, vm_size_t size) {
// expected-note@-1{{MIG callback fails with error after deallocating argument value}}
}
+MIG_SERVER_ROUTINE
+kern_return_t test_ipc_port_release(ipc_port_t port) {
+ ipc_port_release(port); // expected-note{{Value passed through parameter 'port' is deallocated}}
+ return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value}}
+}
+
// Let's try the C++11 attribute spelling syntax as well.
[[clang::mig_server_routine]]
IOReturn test_releaseAsyncReference64(IOExternalMethodArguments *arguments) {
@@ -206,4 +222,10 @@ class MyClient: public IOUserClient {
return kIOReturnError; // expected-warning{{MIG callback fails with error after deallocating argument value}}
// expected-note@-1{{MIG callback fails with error after deallocating argument value}}
}
+
+ IOReturn registerNotificationPort(mach_port_t port, UInt32 x, UInt32 y) {
+ releaseNotificationPort(port); // expected-note{{Value passed through parameter 'port' is deallocated}}
+ return kIOReturnError; // expected-warning{{MIG callback fails with error after deallocating argument value}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value}}
+ }
};
OpenPOWER on IntegriCloud