r338935 - [analyzer] Do not crash in NoStoreFuncVisitor notes if an unexpected region is found.
George Karpenkov via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 3 16:19:08 PDT 2018
Author: george.karpenkov
Date: Fri Aug 3 16:19:07 2018
New Revision: 338935
URL: http://llvm.org/viewvc/llvm-project?rev=338935&view=rev
Log:
[analyzer] Do not crash in NoStoreFuncVisitor notes if an unexpected region is found.
Just do not generate the note at all in that case.
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
cfe/trunk/test/Analysis/diagnostics/no-store-func-path-notes.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=338935&r1=338934&r2=338935&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Fri Aug 3 16:19:07 2018
@@ -351,10 +351,7 @@ public:
ArrayRef<ParmVarDecl *> parameters = getCallParameters(Call);
for (unsigned I = 0; I < Call->getNumArgs() && I < parameters.size(); ++I) {
- Optional<unsigned> AdjustedIdx = Call->getAdjustedParameterIndex(I);
- if (!AdjustedIdx)
- continue;
- const ParmVarDecl *PVD = parameters[*AdjustedIdx];
+ const ParmVarDecl *PVD = parameters[I];
SVal S = Call->getArgSVal(I);
bool ParamIsReferenceType = PVD->getType()->isReferenceType();
std::string ParamName = PVD->getNameAsString();
@@ -565,15 +562,19 @@ private:
SmallString<256> sbuf;
llvm::raw_svector_ostream os(sbuf);
os << "Returning without writing to '";
- prettyPrintRegionName(FirstElement, FirstIsReferenceType, MatchedRegion,
- FieldChain, IndirectionLevel, os);
+
+ // Do not generate the note if failed to pretty-print.
+ if (!prettyPrintRegionName(FirstElement, FirstIsReferenceType,
+ MatchedRegion, FieldChain, IndirectionLevel, os))
+ return nullptr;
os << "'";
return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
}
/// Pretty-print region \p MatchedRegion to \p os.
- void prettyPrintRegionName(StringRef FirstElement, bool FirstIsReferenceType,
+ /// \return Whether printing succeeded.
+ bool prettyPrintRegionName(StringRef FirstElement, bool FirstIsReferenceType,
const MemRegion *MatchedRegion,
const RegionVector &FieldChain,
int IndirectionLevel,
@@ -598,6 +599,7 @@ private:
for (const MemRegion *R : RegionSequence) {
// Just keep going up to the base region.
+ // Element regions may appear due to casts.
if (isa<CXXBaseObjectRegion>(R) || isa<CXXTempObjectRegion>(R))
continue;
@@ -608,6 +610,10 @@ private:
os << Sep;
+ // Can only reasonably pretty-print DeclRegions.
+ if (!isa<DeclRegion>(R))
+ return false;
+
const auto *DR = cast<DeclRegion>(R);
Sep = DR->getValueType()->isAnyPointerType() ? "->" : ".";
DR->getDecl()->getDeclName().print(os, PP);
@@ -617,6 +623,7 @@ private:
prettyPrintFirstElement(FirstElement,
/*MoreItemsExpected=*/false, IndirectionLevel,
os);
+ return true;
}
/// Print first item in the chain, return new separator.
Modified: cfe/trunk/test/Analysis/diagnostics/no-store-func-path-notes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/no-store-func-path-notes.cpp?rev=338935&r1=338934&r2=338935&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/diagnostics/no-store-func-path-notes.cpp (original)
+++ cfe/trunk/test/Analysis/diagnostics/no-store-func-path-notes.cpp Fri Aug 3 16:19:07 2018
@@ -333,3 +333,27 @@ int useMaybeInitializeIndirectlyWithPoin
return z; // expected-warning{{Undefined or garbage value returned to caller}}
// expected-note at -1{{Undefined or garbage value returned to caller}}
}
+
+////////
+
+struct HasFieldA {
+ int x;
+};
+
+struct HasFieldB {
+ int x;
+};
+
+void maybeInitializeHasField(HasFieldA *b) {
+ if (coin()) // expected-note{{Assuming the condition is false}}
+ // expected-note at -1{{Taking false branch}}
+ ((HasFieldB*)b)->x = 120;
+}
+
+int forceElementRegionApperence() {
+ HasFieldA a;
+ maybeInitializeHasField(&a); // expected-note{{Calling 'maybeInitializeHasField'}}
+ // expected-note at -1{{Returning from 'maybeInitializeHasField'}}
+ return ((HasFieldB*)&a)->x; // expected-warning{{Undefined or garbage value returned to caller}}
+ // expected-note at -1{{Undefined or garbage value returned to caller}}
+}
More information about the cfe-commits
mailing list