[analyzer] Add the type of the leaked object to the diagnostic message
If the object is a temporary, and there is no variable it binds to,
let's at least print out the object name in order to help differentiate
it from other temporaries.
rdar://45175098
Differential Revision: https://reviews.llvm.org/D55033
llvm-svn: 347943
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index 608ed88..8758091 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -28,6 +28,17 @@
isa<CXXBoolLiteralExpr>(E);
}
+/// If type represents a pointer to CXXRecordDecl,
+/// and is not a typedef, return the decl name.
+/// Otherwise, return the serialization of type.
+static StringRef getPrettyTypeName(QualType QT) {
+ QualType PT = QT->getPointeeType();
+ if (!PT.isNull() && !QT->getAs<TypedefType>())
+ if (const auto *RD = PT->getAsCXXRecordDecl())
+ return RD->getName();
+ return QT.getAsString();
+}
+
/// Write information about the type state change to {@code os},
/// return whether the note should be generated.
static bool shouldGenerateNote(llvm::raw_string_ostream &os,
@@ -193,7 +204,7 @@
<< Sym->getType().getAsString() << " with a ";
} else if (CurrV.getObjKind() == RetEffect::OS) {
os << " returns an OSObject of type "
- << Sym->getType().getAsString() << " with a ";
+ << getPrettyTypeName(Sym->getType()) << " with a ";
} else if (CurrV.getObjKind() == RetEffect::Generalized) {
os << " returns an object of type " << Sym->getType().getAsString()
<< " with a ";
@@ -432,7 +443,7 @@
if (RegionDescription) {
os << "object allocated and stored into '" << *RegionDescription << '\'';
} else {
- os << "allocated object";
+ os << "allocated object of type " << getPrettyTypeName(Sym->getType());
}
// Get the retain count.
@@ -472,10 +483,10 @@
" Foundation";
}
}
- }
- else
+ } else {
os << " is not referenced later in this execution path and has a retain "
"count of +" << RV->getCount();
+ }
return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
}
@@ -555,6 +566,10 @@
FullSourceLoc SL(AllocStmt->getBeginLoc(), Ctx.getSourceManager());
os << " (allocated on line " << SL.getSpellingLineNumber() << ")";
}
+ } else {
+
+ // If we can't figure out the name, just supply the type information.
+ os << " of type " << getPrettyTypeName(Sym->getType());
}
}