diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index c53b7b1c0acb..d2f81adda1ec 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -432,7 +432,4 @@ void ExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred, B.generateNode(RS, *it, (*it)->getState()); } } - else { - B.takeNodes(dstPreVisit); - } } diff --git a/clang/test/Analysis/malloc-interprocedural.c b/clang/test/Analysis/malloc-interprocedural.c index d3a2ea75083e..0cdd9fb2810b 100644 --- a/clang/test/Analysis/malloc-interprocedural.c +++ b/clang/test/Analysis/malloc-interprocedural.c @@ -69,3 +69,19 @@ void test5() { int *data; my_free1((int*)data); } + +// Test that we keep processing after 'return;' +void fooWithEmptyReturn(int x) { + if (x) + return; + x++; + return; +} + +int uafAndCallsFooWithEmptyReturn() { + int *x = (int*)malloc(12); + free(x); + fooWithEmptyReturn(12); + return *x; // expected-warning {{Use of memory after it is freed}} +} +