diff options
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/Core.cpp | 7 | ||||
-rw-r--r-- | llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp | 47 |
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 |