Skip to content

Commit 9d3adca

Browse files
committed
[CAS] Workaround the issue of MSVC needing default-constructible types for \c std::promise/future.
(cherry picked from commit b12f59b)
1 parent 2073940 commit 9d3adca

File tree

3 files changed

+20
-9
lines changed

3 files changed

+20
-9
lines changed

clang/lib/Frontend/CompileJobCacheResult.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ Error CompileJobCacheResult::forEachOutput(
3737
Error CompileJobCacheResult::forEachLoadedOutput(
3838
llvm::function_ref<Error(Output, std::optional<ObjectProxy>)> Callback) {
3939
// Kick-off materialization for all outputs concurrently.
40-
SmallVector<std::future<Expected<std::optional<ObjectProxy>>>, 4>
41-
FutureOutputs;
40+
SmallVector<std::future<AsyncProxyValue>, 4> FutureOutputs;
4241
size_t Count = getNumOutputs();
4342
for (size_t I = 0; I < Count; ++I) {
4443
ObjectRef Ref = getOutputObject(I);
@@ -49,7 +48,7 @@ Error CompileJobCacheResult::forEachLoadedOutput(
4948
std::optional<Error> OccurredError;
5049
SmallVector<std::optional<ObjectProxy>, 4> Outputs;
5150
for (auto &FutureOutput : FutureOutputs) {
52-
auto Obj = FutureOutput.get();
51+
auto Obj = FutureOutput.get().take();
5352
if (!Obj) {
5453
if (!OccurredError)
5554
OccurredError = Obj.takeError();

llvm/include/llvm/CAS/ObjectStore.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ template <typename T> class unique_function;
2626

2727
namespace cas {
2828

29+
struct AsyncProxyValue;
2930
class ObjectStore;
30-
3131
class ObjectProxy;
3232

3333
/// Content-addressable storage for objects.
@@ -251,8 +251,7 @@ class ObjectStore {
251251
Expected<std::optional<ObjectProxy>> getProxyIfExists(ObjectRef Ref);
252252

253253
/// Asynchronous version of \c getProxyIfExists.
254-
std::future<Expected<std::optional<ObjectProxy>>>
255-
getProxyAsync(ObjectRef Ref);
254+
std::future<AsyncProxyValue> getProxyAsync(ObjectRef Ref);
256255

257256
/// Read the data from \p Data into \p OS.
258257
uint64_t readData(ObjectHandle Node, raw_ostream &OS, uint64_t Offset = 0,
@@ -348,6 +347,20 @@ class ObjectProxy {
348347
ObjectHandle H;
349348
};
350349

350+
/// This is used to workaround the issue of MSVC needing default-constructible
351+
/// types for \c std::promise/future.
352+
struct AsyncProxyValue {
353+
Expected<std::optional<ObjectProxy>> take() { return std::move(Value); }
354+
355+
AsyncProxyValue() : Value(std::nullopt) {}
356+
AsyncProxyValue(Error &&E) : Value(std::move(E)) {}
357+
AsyncProxyValue(ObjectProxy V) : Value(std::move(V)) {}
358+
AsyncProxyValue(std::nullopt_t) : Value(std::nullopt) {}
359+
360+
private:
361+
Expected<std::optional<ObjectProxy>> Value;
362+
};
363+
351364
std::unique_ptr<ObjectStore> createInMemoryCAS();
352365

353366
/// \returns true if \c LLVM_ENABLE_ONDISK_CAS configuration was enabled.

llvm/lib/CAS/ObjectStore.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,8 @@ ObjectStore::getProxyIfExists(ObjectRef Ref) {
117117
return ObjectProxy::load(*this, Ref, *H);
118118
}
119119

120-
std::future<Expected<std::optional<ObjectProxy>>>
121-
ObjectStore::getProxyAsync(ObjectRef Ref) {
122-
std::promise<Expected<std::optional<ObjectProxy>>> Promise;
120+
std::future<AsyncProxyValue> ObjectStore::getProxyAsync(ObjectRef Ref) {
121+
std::promise<AsyncProxyValue> Promise;
123122
auto Future = Promise.get_future();
124123
// FIXME: there is potential for use-after-free for the 'this' pointer.
125124
// Either we should always allocate shared pointers for \c ObjectStore objects

0 commit comments

Comments
 (0)