Index: include/clang/Analysis/ProgramPoint.h =================================================================== --- include/clang/Analysis/ProgramPoint.h +++ include/clang/Analysis/ProgramPoint.h @@ -641,6 +641,10 @@ CallExitBegin(const StackFrameContext *L, const ReturnStmt *RS) : ProgramPoint(RS, CallExitBeginKind, L, nullptr) { } + const ReturnStmt *getReturnStmt() const { + return static_cast(getData1()); + } + private: friend class ProgramPoint; CallExitBegin() = default; Index: lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -37,7 +37,9 @@ check::PostCall, check::NewAllocator, check::Bind, - check::RegionChanges> { + check::RegionChanges, + check::LiveSymbols> { + bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const { return Opts.getBooleanOption("*", false, this) || Opts.getBooleanOption(CallbackName, false, this); @@ -118,6 +120,11 @@ llvm::errs() << "Bind\n"; } + void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SymReaper) const { + if (isCallbackEnabled(State, "LiveSymbols")) + llvm::errs() << "LiveSymbols\n"; + } + ProgramStateRef checkRegionChanges(ProgramStateRef State, const InvalidatedSymbols *Invalidated, Index: lib/StaticAnalyzer/Core/CoreEngine.cpp =================================================================== --- lib/StaticAnalyzer/Core/CoreEngine.cpp +++ lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -315,10 +315,7 @@ const ReturnStmt *RS = nullptr; if (!L.getSrc()->empty()) { if (Optional LastStmt = L.getSrc()->back().getAs()) { - if ((RS = dyn_cast(LastStmt->getStmt()))) { - if (!RS->getRetValue()) - RS = nullptr; - } + RS = dyn_cast(LastStmt->getStmt()); } } Index: lib/StaticAnalyzer/Core/PathDiagnostic.cpp =================================================================== --- lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -742,6 +742,8 @@ return CEE->getCalleeContext()->getCallSite(); if (Optional PIPP = P.getAs()) return PIPP->getInitializer()->getInit(); + if (Optional CEB = P.getAs()) + return CEB->getReturnStmt(); return nullptr; } Index: test/Analysis/return-stmt-merge.cpp =================================================================== --- /dev/null +++ test/Analysis/return-stmt-merge.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder,debug.ExprInspection -analyzer-config debug.AnalysisOrder:PreCall=true,debug.AnalysisOrder:PostCall=true,debug.AnalysisOrder:LiveSymbols=true %s 2>&1 | FileCheck %s + +int coin(); + +void foo() { + int x = coin(); + if (x > 0) + return; + else + return; +} + +void bar() { + foo(); +} + +// CHECK: LiveSymbols +// CHECK-NEXT: LiveSymbols +// CHECK-NEXT: PreCall (foo) +// CHECK-NEXT: LiveSymbols +// CHECK-NEXT: LiveSymbols +// CHECK-NEXT: PreCall (coin) +// CHECK-NEXT: PostCall (coin) +// CHECK-NEXT: LiveSymbols +// CHECK-NEXT: LiveSymbols +// CHECK-NEXT: LiveSymbols +// CHECK-NEXT: PostCall (foo) +// CHECK-NEXT: LiveSymbols +// CHECK-NEXT: LiveSymbols +// CHECK-NEXT: LiveSymbols