Index: cfe/trunk/lib/StaticAnalyzer/Checkers/MIGChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/MIGChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/MIGChecker.cpp @@ -54,11 +54,33 @@ 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 }; Index: cfe/trunk/test/Analysis/mig.mm =================================================================== --- cfe/trunk/test/Analysis/mig.mm +++ cfe/trunk/test/Analysis/mig.mm @@ -15,11 +15,15 @@ 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 @@ 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 @@ // 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 @@ 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}} + } };