Index: lib/StaticAnalyzer/Checkers/MagentaHandleChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MagentaHandleChecker.cpp +++ lib/StaticAnalyzer/Checkers/MagentaHandleChecker.cpp @@ -123,7 +123,9 @@ UNPROCESSED_FUNC, // When a bug is found in function with this flag, do not report this bug // Used to suppress known false positives. - DONOTREPORT_FUNC + DONOTREPORT_FUNC, + // When a function has 'create_sink' annotation , create a sink node. + SINK_FUNC }; enum AnnotationFlag { @@ -144,7 +146,8 @@ // This value is not describing the possible return value of a annotated // function. It basically tell the checker do not report any bugs found in // this function. Used to suppress false positive reports. - DONOTREPORT + DONOTREPORT, + CREATE_SINK }; struct ArgSpec { @@ -416,7 +419,8 @@ {"handle_escape", ESCAPE}, {"handle_use", NOESCAPE}, {"may_fail", BIFURCATE}, - {"suppress_warning", DONOTREPORT}}; + {"suppress_warning", DONOTREPORT}, + {"create_sink", CREATE_SINK}}; // Hard coded FuncSpec for mx_channel_read and mx_channel_write // We currently don't have a clean way to annotate handles passed through @@ -455,6 +459,10 @@ FuncKindMap[FuncDecl] == UNPROCESSED_FUNC || FuncKindMap[FuncDecl] == DONOTREPORT_FUNC) return false; + if (FuncKindMap[FuncDecl] == SINK_FUNC) { + C.generateSink(C.getState(), C.getPredecessor()); + return true; + } } // Check if the function has annotation and has already been processed before if (FuncDeclMap.count(FuncDecl)) @@ -545,6 +553,11 @@ FuncKindMap[FD] = DONOTREPORT_FUNC; return false; } + if (FS.RetAction == CREATE_SINK) { + FuncKindMap[FD] = SINK_FUNC; + Ctx.generateSink(Ctx.getState(), Ctx.getPredecessor()); + return true; + } SmallVector invalidateSVal; ProgramStateRef State = Ctx.getState(); ASTContext &ASTCtx = State->getStateManager().getContext(); @@ -1035,13 +1048,14 @@ HasValidAnnotation = true; } // Return type is not mx_status_t but has annotation other than - // SYMBOLIC|DONOTREPORT Consider it as an error + // SYMBOLIC|DONOTREPORT|CREATE_SINK Consider it as an error if (RetType.getAsString().find(SYSCALL_RETURN_TYPE_NAME) && - (FS.RetAction != SYMBOLIC && FS.RetAction != DONOTREPORT)) + (FS.RetAction != SYMBOLIC && FS.RetAction != DONOTREPORT && + FS.RetAction != CREATE_SINK)) return false; if (FS.RetAction != BIFURCATE && FS.RetAction != SYMBOLIC && - FS.RetAction != DONOTREPORT) + FS.RetAction != DONOTREPORT && FS.RetAction != CREATE_SINK) return false; // Extract ParamDecl's annotation. int ArgId = -1; Index: test/Analysis/mxhandle.c =================================================================== --- test/Analysis/mxhandle.c +++ test/Analysis/mxhandle.c @@ -60,6 +60,8 @@ void noReturnFunc() __attribute__((__noreturn__)); +void sinkFunc() MX_SYSCALL_PARAM_ATTR(create_sink); + int leakingFunc(int argc, char* argv[]) { mx_handle_t sa, sb; mx_channel_create(0, &sa, &sb); @@ -228,6 +230,14 @@ noReturnFunc(); // Should not report any bugs here } +void checkNoLeak17() { + mx_handle_t sa, sb; + if (mx_channel_create(0, &sa, &sb) < 0) { + return; + } + sinkFunc(); // Should not report any bugs here +} + void checkLeak01() { mx_handle_t sa, sb; mx_channel_create(0, &sa, &sb);