RedDocMD updated this revision to Diff 350362.
RedDocMD added a comment.
Made stylistic refactors
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D103750/new/
https://reviews.llvm.org/D103750
Files:
clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
Index: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
@@ -35,9 +35,15 @@
using namespace ento;
namespace {
+
+enum class MakeUniqueKind {
+ Regular, // ie, std::make_unique
+ ForOverwrite, // ie, std::make_unique_for_overwrite
+};
+
class SmartPtrModeling
: public Checker<eval::Call, check::DeadSymbols, check::RegionChanges,
- check::LiveSymbols> {
+ check::LiveSymbols, check::Bind> {
bool isBoolConversionMethod(const CallEvent &Call) const;
@@ -56,6 +62,7 @@
void printState(raw_ostream &Out, ProgramStateRef State, const char *NL,
const char *Sep) const override;
void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const;
+ void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
private:
void handleReset(const CallEvent &Call, CheckerContext &C) const;
@@ -76,10 +83,27 @@
{{"release"}, &SmartPtrModeling::handleRelease},
{{"swap", 1}, &SmartPtrModeling::handleSwap},
{{"get"}, &SmartPtrModeling::handleGet}};
+ const CallDescription StdMakeUniqueCall{{"std", "make_unique"}};
+ const CallDescription StdMakeUniqueForOverwriteCall{
+ {"std", "make_unique_for_overwrite"}};
};
} // end of anonymous namespace
+class MakeUniqueKindWrapper {
+ const MakeUniqueKind Kind;
+
+public:
+ MakeUniqueKindWrapper(MakeUniqueKind Kind) : Kind(Kind) {}
+ MakeUniqueKind get() const { return Kind; }
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddInteger(static_cast<int>(Kind));
+ }
+ bool operator==(const MakeUniqueKind &RHS) const { return Kind == RHS; }
+ bool operator!=(const MakeUniqueKind &RHS) const { return Kind != RHS; }
+};
+
REGISTER_MAP_WITH_PROGRAMSTATE(TrackedRegionMap, const MemRegion *, SVal)
+REGISTER_LIST_WITH_PROGRAMSTATE(MakeUniqueKindList, MakeUniqueKindWrapper)
// Define the inter-checker API.
namespace clang {
@@ -177,7 +201,21 @@
bool SmartPtrModeling::evalCall(const CallEvent &Call,
CheckerContext &C) const {
+
ProgramStateRef State = C.getState();
+
+ if (Call.isCalled(StdMakeUniqueCall)) {
+ State = State->add<MakeUniqueKindList>(MakeUniqueKind::Regular);
+ C.addTransition(State);
+ return true;
+ }
+
+ if (Call.isCalled(StdMakeUniqueForOverwriteCall)) {
+ State = State->add<MakeUniqueKindList>(MakeUniqueKind::ForOverwrite);
+ C.addTransition(State);
+ return true;
+ }
+
if (!smartptr::isStdSmartPtrCall(Call))
return false;
@@ -272,6 +310,46 @@
return C.isDifferent();
}
+bool isUniquePtrType(QualType QT) {
+ if (QT.isNull())
+ return false;
+ const auto *Decl = QT->getAsCXXRecordDecl();
+ if (!Decl || !Decl->getDeclContext()->isStdNamespace())
+ return false;
+ const IdentifierInfo *ID = Decl->getIdentifier();
+ if (!ID)
+ return false;
+ const StringRef Name = ID->getName();
+ return Name == "unique_ptr";
+}
+
+void SmartPtrModeling::checkBind(SVal L, SVal V, const Stmt *S,
+ CheckerContext &C) const {
+ const auto *TVR = dyn_cast_or_null<TypedValueRegion>(L.getAsRegion());
+ if (!TVR)
+ return;
+ if (!isUniquePtrType(TVR->getValueType()))
+ return;
+ const auto *ThisRegion = dyn_cast<MemRegion>(TVR);
+ if (!ThisRegion)
+ return;
+
+ ProgramStateRef State = C.getState();
+ auto KindList = State->get<MakeUniqueKindList>();
+ assert(!KindList.isEmpty() &&
+ "Expected list to contain the kind of the last make_unique");
+ auto Kind = KindList.getHead();
+ if (Kind == MakeUniqueKind::ForOverwrite) {
+ auto RHSVal = C.getSValBuilder().makeNull();
+ State = State->set<TrackedRegionMap>(ThisRegion, RHSVal);
+ } else {
+ // TODO: Encode information that the inner pointer for
+ // unique_ptr made by std::make_unique is *not* null
+ }
+ State = State->set<MakeUniqueKindList>(KindList.getTail());
+ C.addTransition(State);
+}
+
void SmartPtrModeling::checkDeadSymbols(SymbolReaper &SymReaper,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits