Index: clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp @@ -309,6 +309,11 @@ return; } + // If we can find the function body, then dive into it and ignore the + // annotations. + if (FuncDecl->hasBody()) + return; + for (unsigned Arg = 0; Arg < Call.getNumArgs(); ++Arg) { if (Arg >= FuncDecl->getNumParams()) break; @@ -348,6 +353,11 @@ if (!FuncDecl) return; + // If we can find the function body, then dive into it and ignore the + // annotations. + if (FuncDecl->hasBody()) + return; + ProgramStateRef State = C.getState(); std::vector> Notes; Index: clang/test/Analysis/fuchsia_handle.cpp =================================================================== --- clang/test/Analysis/fuchsia_handle.cpp +++ clang/test/Analysis/fuchsia_handle.cpp @@ -315,6 +315,21 @@ // expected-note@-1 {{Potential leak of handle}} } +// Assume this function's declaration that has the release annotation is in one +// header file while its implementation is in another file. We have to annotate +// the declaration because it might be used outside the TU. +// We also want to make sure it is okay to call the function within the same TU. +zx_status_t test_release_handle(zx_handle_t handle ZX_HANDLE_RELEASE) { + return zx_handle_close(handle); +} + +void checkReleaseImplementedFunc() { + zx_handle_t a, b; + zx_channel_create(0, &a, &b); + zx_handle_close(a); + test_release_handle(b); +} + // RAII template