Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -297,6 +297,7 @@ MemRegionManager &MmrMgr; const SourceManager &SM; const PrintingPolicy &PP; + bugreporter::TrackingKind TKind; /// Recursion limit for dereferencing fields when looking for the /// region of interest. @@ -317,10 +318,10 @@ using RegionVector = SmallVector; public: - NoStoreFuncVisitor(const SubRegion *R) + NoStoreFuncVisitor(const SubRegion *R, bugreporter::TrackingKind TKind) : RegionOfInterest(R), MmrMgr(*R->getMemRegionManager()), SM(MmrMgr.getContext().getSourceManager()), - PP(MmrMgr.getContext().getPrintingPolicy()) {} + PP(MmrMgr.getContext().getPrintingPolicy()), TKind(TKind) {} void Profile(llvm::FoldingSetNodeID &ID) const override { static int Tag = 0; @@ -611,6 +612,9 @@ } while (N); } +static llvm::StringLiteral WillBeUsedForACondition = + ", which will be (a part of a) condition"; + std::shared_ptr NoStoreFuncVisitor::maybeEmitNote( BugReport &R, const CallEvent &Call, const ExplodedNode *N, const RegionVector &FieldChain, const MemRegion *MatchedRegion, @@ -657,6 +661,8 @@ return nullptr; os << "'"; + if (TKind == bugreporter::TrackingKind::Condition) + os << WillBeUsedForACondition; return std::make_shared(L, os.str()); } @@ -1068,6 +1074,9 @@ if (!L.isValid() || !L.asLocation().isValid()) return nullptr; + if (TKind == bugreporter::TrackingKind::Condition) + Out << WillBeUsedForACondition; + auto EventPiece = std::make_shared(L, Out.str()); // If we determined that the note is meaningless, make it prunable, and @@ -1485,6 +1494,9 @@ if (os.str().empty()) showBRDefaultDiagnostics(os, R, V); + if (TKind == bugreporter::TrackingKind::Condition) + os << WillBeUsedForACondition; + // Construct a new PathDiagnosticPiece. ProgramPoint P = StoreSite->getLocation(); PathDiagnosticLocation L; @@ -1971,7 +1983,7 @@ // Mark both the variable region and its contents as interesting. SVal V = LVState->getRawSVal(loc::MemRegionVal(R)); report.addVisitor( - llvm::make_unique(cast(R))); + llvm::make_unique(cast(R), TKind)); MacroNullReturnSuppressionVisitor::addMacroVisitorIfNecessary( LVNode, R, EnableNullFPSuppression, report, V); Index: clang/test/Analysis/track-control-dependency-conditions.cpp =================================================================== --- clang/test/Analysis/track-control-dependency-conditions.cpp +++ clang/test/Analysis/track-control-dependency-conditions.cpp @@ -29,7 +29,7 @@ bool coin(); void foo() { - flag = coin(); // tracking-note{{Value assigned to 'flag'}} + flag = coin(); // tracking-note{{Value assigned to 'flag', which will be (a part of a) condition}} } void test() { @@ -58,7 +58,7 @@ bool coin(); void foo() { - flag = coin(); // tracking-note{{Value assigned to 'flag'}} + flag = coin(); // tracking-note{{Value assigned to 'flag', which will be (a part of a) condition}} } void test() { @@ -90,8 +90,8 @@ void foo() { // coin() could write bar, do it's invalidated. - flag = coin(); // tracking-note{{Value assigned to 'flag'}} - // tracking-note@-1{{Value assigned to 'bar'}} + flag = coin(); // tracking-note{{Value assigned to 'flag', which will be (a part of a) condition}} + // tracking-note@-1{{Value assigned to 'bar', which will be (a part of a) condition}} } int bar; @@ -184,14 +184,14 @@ int *getIntPtr(); void storeValue(int **i) { - *i = getIntPtr(); // tracking-note{{Value assigned to 'i'}} + *i = getIntPtr(); // tracking-note{{Value assigned to 'i', which will be (a part of a) condition}} } int *conjurePointer() { int *i; storeValue(&i); // tracking-note{{Calling 'storeValue'}} // tracking-note@-1{{Returning from 'storeValue'}} - return i; // tracking-note{{Returning pointer (loaded from 'i')}} + return i; // tracking-note{{Returning pointer (loaded from 'i'), which will be (a part of a) condition}} } void f(int *ptr) { @@ -280,7 +280,7 @@ // tracking-note@-1{{Taking false branch}} // debug-note@-2{{Tracking condition 'coin()'}} return true; - return coin(); // tracking-note{{Returning value}} + return coin(); // tracking-note{{Returning value, which will be (a part of a) condition}} } void i(int *ptr) { @@ -366,7 +366,7 @@ void foo() { int y; y = 1; - flag = y; // tracking-note{{The value 1 is assigned to 'flag'}} + flag = y; // tracking-note{{The value 1 is assigned to 'flag', which will be (a part of a) condition}} } void f(int y) { @@ -388,7 +388,7 @@ int getInt(); void foo() { - flag = getInt(); // tracking-note{{Value assigned to 'flag'}} + flag = getInt(); // tracking-note{{Value assigned to 'flag', which will be (a part of a) condition}} } void f() { @@ -701,7 +701,7 @@ bool coin(); void bar(int &flag) { - flag = coin(); // tracking-note{{Value assigned to 'flag'}} + flag = coin(); // tracking-note{{Value assigned to 'flag', which will be (a part of a) condition}} } void bar2(int &flag2) {