summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/ExecutionEngine/Orc/Core.cpp7
-rw-r--r--llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp47
2 files changed, 51 insertions, 3 deletions
diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp
index 82be34476f6..894e210da13 100644
--- a/llvm/lib/ExecutionEngine/Orc/Core.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp
@@ -468,6 +468,8 @@ void VSO::resolve(const SymbolMap &Resolved) {
for (const auto &KV : Resolved) {
auto &Name = KV.first;
auto Sym = KV.second;
+ JITSymbolFlags ResolvedFlags = Sym.getFlags();
+ ResolvedFlags &= ~JITSymbolFlags::Weak;
assert(!Sym.getFlags().isLazy() && !Sym.getFlags().isMaterializing() &&
"Materializing flags should be managed internally");
@@ -480,13 +482,11 @@ void VSO::resolve(const SymbolMap &Resolved) {
"Symbol should be materializing");
assert(I->second.getAddress() == 0 && "Symbol has already been resolved");
- assert(Sym.getFlags() ==
+ assert(ResolvedFlags ==
JITSymbolFlags::stripTransientFlags(I->second.getFlags()) &&
"Resolved flags should match the declared flags");
// Once resolved, symbols can never be weak.
- JITSymbolFlags ResolvedFlags = Sym.getFlags();
- ResolvedFlags &= ~JITSymbolFlags::Weak;
ResolvedFlags |= JITSymbolFlags::Materializing;
I->second = JITEvaluatedSymbol(Sym.getAddress(), ResolvedFlags);
@@ -748,6 +748,7 @@ void VSO::lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
for (auto &KV : MU->getSymbols()) {
auto SymK = Symbols.find(KV.first);
auto Flags = SymK->second.getFlags();
+ Flags &= ~JITSymbolFlags::Weak;
Flags &= ~JITSymbolFlags::Lazy;
Flags |= JITSymbolFlags::Materializing;
SymK->second.setFlags(Flags);
diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
index c8f30dbfd94..589cdb4d745 100644
--- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
@@ -10,6 +10,7 @@
#include "OrcTestCommon.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include "gtest/gtest.h"
#include <set>
@@ -768,4 +769,50 @@ TEST(CoreAPIsTest, TestGetRequestedSymbolsAndDelegate) {
EXPECT_TRUE(BarMaterialized) << "Bar should be materialized now";
}
+TEST(CoreAPIsTest, TestMaterializeWeakSymbol) {
+ // Confirm that once a weak definition is selected for materialization it is
+ // treated as strong.
+
+ constexpr JITTargetAddress FakeFooAddr = 0xdeadbeef;
+ JITSymbolFlags FooFlags = JITSymbolFlags::Exported;
+ FooFlags &= JITSymbolFlags::Weak;
+ auto FooSym = JITEvaluatedSymbol(FakeFooAddr, FooFlags);
+
+ ExecutionSession ES;
+ auto Foo = ES.getSymbolStringPool().intern("foo");
+
+ auto &V = ES.createVSO("V");
+
+ std::unique_ptr<MaterializationResponsibility> FooResponsibility;
+ auto MU = llvm::make_unique<SimpleMaterializationUnit>(
+ SymbolFlagsMap({{Foo, FooFlags}}), [&](MaterializationResponsibility R) {
+ FooResponsibility =
+ llvm::make_unique<MaterializationResponsibility>(std::move(R));
+ });
+
+ cantFail(V.define(MU));
+ auto Q = std::make_shared<AsynchronousSymbolQuery>(
+ SymbolNameSet({Foo}),
+ [](Expected<AsynchronousSymbolQuery::ResolutionResult> R) {
+ cantFail(std::move(R));
+ },
+ [](Error Err) { cantFail(std::move(Err)); });
+ V.lookup(std::move(Q), SymbolNameSet({Foo}));
+
+ auto MU2 = llvm::make_unique<SimpleMaterializationUnit>(
+ SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
+ [](MaterializationResponsibility R) {
+ llvm_unreachable("This unit should never be materialized");
+ });
+
+ auto Err = V.define(MU2);
+ EXPECT_TRUE(!!Err) << "Expected failure value";
+ EXPECT_TRUE(Err.isA<DuplicateDefinition>())
+ << "Expected a duplicate definition error";
+ consumeError(std::move(Err));
+
+ FooResponsibility->resolve(SymbolMap({{Foo, FooSym}}));
+ FooResponsibility->finalize();
+}
+
} // namespace
OpenPOWER on IntegriCloud