diff options
author | Lang Hames <lhames@apple.com> | 2025-05-09 17:06:36 +1000 |
---|---|---|
committer | Lang Hames <lhames@apple.com> | 2025-05-09 17:30:42 +1000 |
commit | b0979b8c65d76cc1897e97b9ad091d8d99abdd18 (patch) | |
tree | d8eb5c908105b663acf0f6a1ffe01e58f8f13ec2 | |
parent | 60b62c65bd693fa104d913bb401de3b992902520 (diff) | |
download | llvm-b0979b8c65d76cc1897e97b9ad091d8d99abdd18.zip llvm-b0979b8c65d76cc1897e97b9ad091d8d99abdd18.tar.gz llvm-b0979b8c65d76cc1897e97b9ad091d8d99abdd18.tar.bz2 |
[ORC] Add optional context string to duplicate symbol definition errors.
The context string can be added to indicate the source of the duplicate
definition. E.g. if the context is set to "foo2.o", then:
"Duplicate definition of symbol 'foo'"
becomes
"In foo2.o, duplicate definition of symbol 'foo'".
The JITDylib::defineImpl method is updated to use the name of the
MaterializationUnit being added as the context string for duplicate definition
errors. The JITDylib::defineMaterializing method is updated to use
"defineMaterializing operation" as the conext string.
5 files changed, 32 insertions, 6 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h index 8dffea7..d42fc3e 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcError.h @@ -48,12 +48,16 @@ class DuplicateDefinition : public ErrorInfo<DuplicateDefinition> { public: static char ID; - DuplicateDefinition(std::string SymbolName); + DuplicateDefinition(std::string SymbolName, + std::optional<std::string> Context = {}); std::error_code convertToErrorCode() const override; void log(raw_ostream &OS) const override; const std::string &getSymbolName() const; + const std::optional<std::string> &getContext() const; + private: std::string SymbolName; + std::optional<std::string> Context; }; class JITSymbolNotFound : public ErrorInfo<JITSymbolNotFound> { diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp index cbed057..88bdba0 100644 --- a/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -731,7 +731,8 @@ JITDylib::defineMaterializing(MaterializationResponsibility &FromMR, Symbols.erase(Symbols.find_as(S)); // FIXME: Return all duplicates. - return make_error<DuplicateDefinition>(std::string(*Name)); + return make_error<DuplicateDefinition>( + std::string(*Name), "defineMaterializing operation"); } // Otherwise just make a note to discard this symbol after the loop. @@ -1424,7 +1425,8 @@ Error JITDylib::defineImpl(MaterializationUnit &MU) { if (!Duplicates.empty()) { LLVM_DEBUG( { dbgs() << " Error: Duplicate symbols " << Duplicates << "\n"; }); - return make_error<DuplicateDefinition>(std::string(**Duplicates.begin())); + return make_error<DuplicateDefinition>(std::string(**Duplicates.begin()), + MU.getName().str()); } // Discard any overridden defs in this MU. diff --git a/llvm/lib/ExecutionEngine/Orc/Shared/OrcError.cpp b/llvm/lib/ExecutionEngine/Orc/Shared/OrcError.cpp index ec53338..0612078 100644 --- a/llvm/lib/ExecutionEngine/Orc/Shared/OrcError.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Shared/OrcError.cpp @@ -86,21 +86,28 @@ std::error_code orcError(OrcErrorCode ErrCode) { return std::error_code(static_cast<UT>(ErrCode), getOrcErrCat()); } -DuplicateDefinition::DuplicateDefinition(std::string SymbolName) - : SymbolName(std::move(SymbolName)) {} +DuplicateDefinition::DuplicateDefinition(std::string SymbolName, + std::optional<std::string> Context) + : SymbolName(std::move(SymbolName)), Context(std::move(Context)) {} std::error_code DuplicateDefinition::convertToErrorCode() const { return orcError(OrcErrorCode::DuplicateDefinition); } void DuplicateDefinition::log(raw_ostream &OS) const { - OS << "Duplicate definition of symbol '" << SymbolName << "'"; + if (Context) + OS << "In " << *Context << ", "; + OS << "duplicate definition of symbol '" << SymbolName << "'"; } const std::string &DuplicateDefinition::getSymbolName() const { return SymbolName; } +const std::optional<std::string> &DuplicateDefinition::getContext() const { + return Context; +} + JITSymbolNotFound::JITSymbolNotFound(std::string SymbolName) : SymbolName(std::move(SymbolName)) {} diff --git a/llvm/test/ExecutionEngine/JITLink/Generic/Inputs/main-ret-42.ll b/llvm/test/ExecutionEngine/JITLink/Generic/Inputs/main-ret-42.ll new file mode 100644 index 0000000..ebfdd93 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/Generic/Inputs/main-ret-42.ll @@ -0,0 +1,4 @@ +define i32 @main(i32 %argc, i8** %argv) { +entry: + ret i32 42 +} diff --git a/llvm/test/ExecutionEngine/JITLink/Generic/duplicate-definition-error.test b/llvm/test/ExecutionEngine/JITLink/Generic/duplicate-definition-error.test new file mode 100644 index 0000000..4b5ac73 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/Generic/duplicate-definition-error.test @@ -0,0 +1,9 @@ +# RUN: rm -rf %t && mkdir %t +# RUN: llc -filetype=obj -o %t/main-ret-0.o %S/Inputs/main-ret-0.ll +# RUN: llc -filetype=obj -o %T/main-ret-42.o %S/Inputs/main-ret-42.ll +# RUN: not llvm-jitlink -noexec %T/main-ret-0.o %T/main-ret-42.o 2>&1 | FileCheck %s +# +# Trigger a duplicate definition error by trying to link two main functions, +# check that the error message includes the file that introduced the duplicate. +# +# CHECK: In {{.*}}main-ret-42.o, duplicate definition of {{.*}}main |