Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -887,15 +887,6 @@ RetE = RetE->IgnoreParenCasts(); - // If we can't prove the return value is 0, just mark it interesting, and - // make sure to track it into any further inner functions. - if (!State->isNull(V).isConstrainedTrue()) { - BR.markInteresting(V); - ReturnVisitor::addVisitorIfNecessary(N, RetE, BR, - EnableNullFPSuppression); - return nullptr; - } - // If we're returning 0, we should track where that 0 came from. bugreporter::trackNullOrUndefValue(N, RetE, BR, /*IsArg*/ false, EnableNullFPSuppression); @@ -904,20 +895,33 @@ SmallString<64> Msg; llvm::raw_svector_ostream Out(Msg); - if (V.getAs()) { - // If we have counter-suppression enabled, make sure we keep visiting - // future nodes. We want to emit a path note as well, in case - // the report is resurrected as valid later on. - if (EnableNullFPSuppression && - Options.shouldAvoidSuppressingNullArgumentPaths()) - Mode = MaybeUnsuppress; + if (State->isNull(V).isConstrainedTrue()) { + if (V.getAs()) { + + // If we have counter-suppression enabled, make sure we keep visiting + // future nodes. We want to emit a path note as well, in case + // the report is resurrected as valid later on. + if (EnableNullFPSuppression && + Options.shouldAvoidSuppressingNullArgumentPaths()) + Mode = MaybeUnsuppress; + + if (RetE->getType()->isObjCObjectPointerType()) { + Out << "Returning nil"; + } else { + Out << "Returning null pointer"; + } + } else { + Out << "Returning zero"; + } - if (RetE->getType()->isObjCObjectPointerType()) - Out << "Returning nil"; - else - Out << "Returning null pointer"; } else { - Out << "Returning zero"; + if (auto CI = V.getAs()) { + Out << "Returning the value " << CI->getValue(); + } else if (V.getAs()) { + Out << "Returning pointer"; + } else { + Out << "Returning value"; + } } if (LValue) { @@ -1262,10 +1266,9 @@ InitE = InitE->IgnoreParenCasts(); bugreporter::trackNullOrUndefValue(StoreSite, InitE, BR, IsParam, EnableNullFPSuppression); - } else { - ReturnVisitor::addVisitorIfNecessary(StoreSite, InitE->IgnoreParenCasts(), - BR, EnableNullFPSuppression); } + ReturnVisitor::addVisitorIfNecessary(StoreSite, InitE->IgnoreParenCasts(), + BR, EnableNullFPSuppression); } // Okay, we've found the binding. Emit an appropriate message. Index: clang/test/Analysis/diagnostics/track_subexpressions.cpp =================================================================== --- clang/test/Analysis/diagnostics/track_subexpressions.cpp +++ clang/test/Analysis/diagnostics/track_subexpressions.cpp @@ -5,15 +5,15 @@ #define UINT8_MAX 255 #define TCP_MAXWIN 65535 -uint8_t bar() { - uint8_t rcvscale = UINT8_MAX; - return rcvscale; +uint8_t get_uint8_max() { + uint8_t rcvscale = UINT8_MAX; // expected-note{{'rcvscale' initialized to 255}} + return rcvscale; // expected-note{{Returning the value 255 (loaded from 'rcvscale')}} } -void foo() { - uint8_t shift_amount = bar(); // expected-note{{'shift_amount' initialized to 255}} - // expected-note@-1{{Calling 'bar'}} - // expected-note@-2{{Returning from 'bar'}} +void shift_by_undefined_value() { + uint8_t shift_amount = get_uint8_max(); // expected-note{{'shift_amount' initialized to 255}} + // expected-note@-1{{Calling 'get_uint8_max'}} + // expected-note@-2{{Returning from 'get_uint8_max'}} (void)(TCP_MAXWIN << shift_amount); // expected-warning{{The result of the left shift is undefined due to shifting by '255', which is greater or equal to the width of type 'int'}} // expected-note@-1{{The result of the left shift is undefined due to shifting by '255', which is greater or equal to the width of type 'int'}} } Index: clang/test/Analysis/uninit-const.cpp =================================================================== --- clang/test/Analysis/uninit-const.cpp +++ clang/test/Analysis/uninit-const.cpp @@ -49,7 +49,8 @@ int& f6_1_sub(int &p) { - return p; + return p; // expected-note{{Returning without writing to 'p'}} + // expected-note@-1{{Returning pointer (reference to 't')}} } void f6_1(void) { @@ -58,6 +59,7 @@ //expected-note@-1 {{Calling 'f6_1_sub'}} //expected-note@-2 {{Returning from 'f6_1_sub'}} //expected-note@-3 {{Assigned value is garbage or undefined}} + //expected-note@-4{{Passing value via 1st parameter 'p'}} int q = p; doStuff6(q); }