[llvm-dis] Fix non-deterministic disassembly across multiple inputs (#110988)
Prior to this patch, the LLVMContext was shared across inputs to llvm-dis. Consequently, NamedStructTypes was shared across inputs, which impacts StructType::setName - if a name was reused across inputs, it would get renamed during construction of the struct type, leading to tricky to diagnose confusion.
This commit is contained in:
15
llvm/test/tools/llvm-dis/multiple-files-equivalent.ll
Normal file
15
llvm/test/tools/llvm-dis/multiple-files-equivalent.ll
Normal file
@@ -0,0 +1,15 @@
|
||||
; RUN: llvm-as -o %t0 %s
|
||||
; RUN: cp %t0 %t1
|
||||
; RUN: llvm-dis %t0 %t1
|
||||
; RUN: FileCheck %s < %t0.ll
|
||||
; RUN: FileCheck %s < %t1.ll
|
||||
|
||||
; Test that if we disassemble the same bitcode twice, the type names are
|
||||
; unchanged between the two. This protects against a bug whereby state was
|
||||
; preserved across inputs and the types ended up with different names.
|
||||
|
||||
; CHECK: %Foo = type { ptr }
|
||||
%Foo = type { ptr }
|
||||
|
||||
; CHECK: @foo = global %Foo zeroinitializer
|
||||
@foo = global %Foo zeroinitializer
|
||||
@@ -191,10 +191,6 @@ int main(int argc, char **argv) {
|
||||
if (LoadBitcodeIntoNewDbgInfoFormat == cl::boolOrDefault::BOU_UNSET)
|
||||
LoadBitcodeIntoNewDbgInfoFormat = cl::boolOrDefault::BOU_TRUE;
|
||||
|
||||
LLVMContext Context;
|
||||
Context.setDiagnosticHandler(
|
||||
std::make_unique<LLVMDisDiagnosticHandler>(argv[0]));
|
||||
|
||||
if (InputFilenames.size() < 1) {
|
||||
InputFilenames.push_back("-");
|
||||
} else if (InputFilenames.size() > 1 && !OutputFilename.empty()) {
|
||||
@@ -204,6 +200,12 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
for (const auto &InputFilename : InputFilenames) {
|
||||
// Use a fresh context for each input to avoid state
|
||||
// cross-contamination across inputs (e.g. type name collisions).
|
||||
LLVMContext Context;
|
||||
Context.setDiagnosticHandler(
|
||||
std::make_unique<LLVMDisDiagnosticHandler>(argv[0]));
|
||||
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
|
||||
MemoryBuffer::getFileOrSTDIN(InputFilename);
|
||||
if (std::error_code EC = BufferOrErr.getError()) {
|
||||
|
||||
Reference in New Issue
Block a user