libutil: explicitly mark ref(shared_ptr) as unsafe

we'll also assert instead of throwing an exception because that just
seems more useful. this should never *ever* happen, and it is on the
callers of such conversions to ensure that the conversion *is* safe.

Change-Id: Ib0696af4f037046f2d45bf5b1b255393ea9b5f05
This commit is contained in:
eldritch horrors
2025-04-05 21:57:45 +02:00
parent dd8dbb56fc
commit 949a561540
11 changed files with 34 additions and 25 deletions
+4 -4
View File
@@ -47,7 +47,7 @@ ref<LocalStore> ensureLocalStore()
{
auto store2 = std::dynamic_pointer_cast<LocalStore>(store);
if (!store2) throw Error("you don't have sufficient rights to use this command");
return ref<LocalStore>(store2);
return ref<LocalStore>::unsafeFromPtr(store2);
}
@@ -159,7 +159,7 @@ static void opRealise(AsyncIoRoot & aio, Strings opFlags, Strings opArgs)
if (settings.printMissing) {
aio.blockOn(printMissing(
ref<Store>(store), willBuild, willSubstitute, unknown, downloadSize, narSize
ref<Store>::unsafeFromPtr(store), willBuild, willSubstitute, unknown, downloadSize, narSize
));
}
@@ -451,7 +451,7 @@ static void opQuery(AsyncIoRoot & aio, Strings opFlags, Strings opArgs)
for (auto & i : opArgs)
for (auto & j : aio.blockOn(maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise)))
roots.insert(j);
aio.blockOn(printDotGraph(ref<Store>(store), std::move(roots)));
aio.blockOn(printDotGraph(ref<Store>::unsafeFromPtr(store), std::move(roots)));
break;
}
@@ -460,7 +460,7 @@ static void opQuery(AsyncIoRoot & aio, Strings opFlags, Strings opArgs)
for (auto & i : opArgs)
for (auto & j : aio.blockOn(maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise)))
roots.insert(j);
aio.blockOn(printGraphML(ref<Store>(store), std::move(roots)));
aio.blockOn(printGraphML(ref<Store>::unsafeFromPtr(store), std::move(roots)));
break;
}
+1 -1
View File
@@ -118,7 +118,7 @@ ref<eval_cache::CachingEvaluator> EvalCommand::getEvaluator()
evalState->repair = repair;
}
return ref<eval_cache::CachingEvaluator>(evalState);
return ref<eval_cache::CachingEvaluator>::unsafeFromPtr(evalState);
}
MixOperateOnOptions::MixOperateOnOptions()
+2 -2
View File
@@ -526,7 +526,7 @@ ref<AttrCursor> AttrCursor::getAttr(EvalState & state, const std::string & name)
auto p = maybeGetAttr(state, name);
if (!p)
throw Error("attribute '%s' does not exist", getAttrPathStr(state, name));
return ref(p);
return ref<AttrCursor>::unsafeFromPtr(p);
}
OrSuggestions<ref<AttrCursor>> AttrCursor::findAlongAttrPath(EvalState & state, const std::vector<std::string> & attrPath)
@@ -540,7 +540,7 @@ OrSuggestions<ref<AttrCursor>> AttrCursor::findAlongAttrPath(EvalState & state,
}
res = child;
}
return ref(res);
return ref<AttrCursor>::unsafeFromPtr(res);
}
std::string AttrCursor::getString(EvalState & state)
+1 -1
View File
@@ -333,7 +333,7 @@ Evaluator::Evaluator(
, builtins(mem, symbols, paths.searchPath(), store->config().storeDir)
, repair(NoRepair)
, store(store)
, buildStore(buildStore ? ref(buildStore) : store)
, buildStore(buildStore ? ref<Store>::unsafeFromPtr(buildStore) : store)
, debug{
debugRepl ? std::make_unique<DebugState>(
positions,
+1 -1
View File
@@ -387,7 +387,7 @@ template<> struct BuildAST<grammar::v1::inherit> : change_head<InheritState> {
if (s.from != nullptr) {
if (!b.attrs.inheritFromExprs)
b.attrs.inheritFromExprs = std::make_unique<std::vector<ref<Expr>>>();
auto fromExpr = ref<Expr>(std::move(s.from));
auto fromExpr = ref<Expr>::unsafeFromPtr(std::move(s.from));
b.attrs.inheritFromExprs->push_back(fromExpr);
for (auto & i : s.attrs) {
if (attrs.find(i.symbol) != attrs.end())
+7 -3
View File
@@ -1310,9 +1310,13 @@ void LocalDerivationGoal::startDaemon()
params["root"] = *optRoot;
params["state"] = "/no-such-path";
params["log"] = "/no-such-path";
auto store = make_ref<RestrictedStore>(params,
ref<LocalStore>(std::dynamic_pointer_cast<LocalStore>(worker.store.shared_from_this())),
*this);
auto store = make_ref<RestrictedStore>(
params,
ref<LocalStore>::unsafeFromPtr(
std::dynamic_pointer_cast<LocalStore>(worker.store.shared_from_this())
),
*this
);
addedPaths.clear();
+1 -1
View File
@@ -80,7 +80,7 @@ struct LocalStoreAccessor : public FSAccessor
ref<FSAccessor> LocalFSStore::getFSAccessor()
{
return make_ref<LocalStoreAccessor>(ref<LocalFSStore>(
return make_ref<LocalStoreAccessor>(ref<LocalFSStore>::unsafeFromPtr(
std::dynamic_pointer_cast<LocalFSStore>(shared_from_this())));
}
+3 -3
View File
@@ -715,7 +715,7 @@ try {
stats.narInfoReadAverted++;
if (!res->didExist())
throw InvalidPath("path '%s' does not exist in the store", printStorePath(storePath));
co_return ref<const ValidPathInfo>(res->value);
co_return ref<const ValidPathInfo>::unsafeFromPtr(res->value);
}
}
@@ -730,7 +730,7 @@ try {
if (res.first == NarInfoDiskCache::oInvalid)
throw InvalidPath("path '%s' does not exist in the store", printStorePath(storePath));
}
co_return ref<const ValidPathInfo>(res.second);
co_return ref<const ValidPathInfo>::unsafeFromPtr(res.second);
}
}
@@ -754,7 +754,7 @@ try {
throw InvalidPath("path '%s' does not exist in the store", printStorePath(storePath));
}
co_return ref<const ValidPathInfo>(info);
co_return ref<const ValidPathInfo>::unsafeFromPtr(info);
} catch (...) {
co_return result::current_exception();
}
+1 -1
View File
@@ -132,7 +132,7 @@ public:
{
auto state_(pool.state.lock());
if (!bad)
state_->idle.push_back(ref<R>(r));
state_->idle.push_back(ref<R>::unsafeFromPtr(r));
assert(state_->inUse);
state_->inUse--;
state_->notify();
+11 -6
View File
@@ -1,6 +1,7 @@
#pragma once
///@file
#include <cassert>
#include <compare>
#include <memory>
#include <exception>
@@ -20,17 +21,21 @@ private:
std::shared_ptr<T> p;
explicit ref<T>(const std::shared_ptr<T> & p)
: p(p)
{
assert(p);
}
public:
ref(const ref<T> & r)
: p(r.p)
{ }
explicit ref<T>(const std::shared_ptr<T> & p)
: p(p)
static ref<T> unsafeFromPtr(const std::shared_ptr<T> & p)
{
if (!p)
throw std::invalid_argument("null pointer cast to ref");
return ref(p);
}
template<std::derived_from<std::enable_shared_from_this<T>> T2>
@@ -62,7 +67,7 @@ public:
std::optional<ref<T2>> try_cast() const
{
if (auto d = std::dynamic_pointer_cast<T2>(p)) {
return ref<T2>(d);
return ref<T2>::unsafeFromPtr(d);
} else {
return std::nullopt;
}
@@ -77,7 +82,7 @@ public:
template<typename T2>
operator ref<T2> () const
{
return ref<T2>((std::shared_ptr<T2>) p);
return ref<T2>::unsafeFromPtr((std::shared_ptr<T2>) p);
}
ref<T> & operator=(ref<T> const & rhs) = default;
+2 -2
View File
@@ -34,7 +34,7 @@ static AsyncIoRoot & aio()
static ref<Store> store()
{
static std::shared_ptr<Store> _store;
static std::optional<ref<Store>> _store;
if (!_store) {
try {
initLibStore();
@@ -43,7 +43,7 @@ static ref<Store> store()
croak("%s", e.what());
}
}
return ref<Store>(_store);
return *_store;
}