aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/AsmParser/LLParser.h10
-rw-r--r--llvm/include/llvm/AsmParser/Parser.h8
-rw-r--r--llvm/include/llvm/Bitcode/BitcodeReader.h32
-rw-r--r--llvm/include/llvm/CodeGen/MIRParser/MIRParser.h7
-rw-r--r--llvm/include/llvm/IRReader/IRReader.h6
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp44
-rw-r--r--llvm/lib/AsmParser/Parser.cpp9
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp64
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIRParser.cpp6
-rw-r--r--llvm/test/Assembler/invalid-datalayout-override.ll7
-rw-r--r--llvm/test/Bitcode/function-default-address-spaces.ll4
-rw-r--r--llvm/tools/llc/llc.cpp4
-rw-r--r--llvm/tools/llvm-as/llvm-as.cpp2
-rw-r--r--llvm/tools/llvm-reduce/ReducerWorkItem.cpp4
-rw-r--r--llvm/tools/opt/opt.cpp2
-rw-r--r--llvm/unittests/AsmParser/AsmParserTest.cpp37
16 files changed, 167 insertions, 79 deletions
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index 2f39803..b07e9fc 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -179,8 +179,10 @@ namespace llvm {
Lex(F, SM, Err, Context), M(M), Index(Index), Slots(Slots),
BlockAddressPFS(nullptr) {}
bool Run(
- bool UpgradeDebugInfo, DataLayoutCallbackTy DataLayoutCallback =
- [](StringRef) { return std::nullopt; });
+ bool UpgradeDebugInfo,
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef, StringRef) {
+ return std::nullopt;
+ });
bool parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots);
@@ -318,8 +320,8 @@ namespace llvm {
bool parseTopLevelEntities();
bool validateEndOfModule(bool UpgradeDebugInfo);
bool validateEndOfIndex();
- bool parseTargetDefinitions();
- bool parseTargetDefinition();
+ bool parseTargetDefinitions(DataLayoutCallbackTy DataLayoutCallback);
+ bool parseTargetDefinition(std::string &TentativeDLStr, LocTy &DLStrLoc);
bool parseModuleAsm();
bool parseSourceFileName();
bool parseUnnamedType();
diff --git a/llvm/include/llvm/AsmParser/Parser.h b/llvm/include/llvm/AsmParser/Parser.h
index 5fbb94d..c57e7ab 100644
--- a/llvm/include/llvm/AsmParser/Parser.h
+++ b/llvm/include/llvm/AsmParser/Parser.h
@@ -29,7 +29,7 @@ struct SlotMapping;
class SMDiagnostic;
class Type;
-typedef llvm::function_ref<std::optional<std::string>(StringRef)>
+typedef llvm::function_ref<std::optional<std::string>(StringRef, StringRef)>
DataLayoutCallbackTy;
/// This function is a main interface to the LLVM Assembly Parser. It parses
@@ -86,7 +86,7 @@ struct ParsedModuleAndIndex {
ParsedModuleAndIndex parseAssemblyFileWithIndex(
StringRef Filename, SMDiagnostic &Err, LLVMContext &Context,
SlotMapping *Slots = nullptr,
- DataLayoutCallbackTy DataLayoutCallback = [](StringRef) {
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef, StringRef) {
return std::nullopt;
});
@@ -127,7 +127,7 @@ parseSummaryIndexAssemblyString(StringRef AsmString, SMDiagnostic &Err);
std::unique_ptr<Module> parseAssembly(
MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context,
SlotMapping *Slots = nullptr,
- DataLayoutCallbackTy DataLayoutCallback = [](StringRef) {
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef, StringRef) {
return std::nullopt;
});
@@ -169,7 +169,7 @@ parseSummaryIndexAssembly(MemoryBufferRef F, SMDiagnostic &Err);
bool parseAssemblyInto(
MemoryBufferRef F, Module *M, ModuleSummaryIndex *Index, SMDiagnostic &Err,
SlotMapping *Slots = nullptr,
- DataLayoutCallbackTy DataLayoutCallback = [](StringRef) {
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef, StringRef) {
return std::nullopt;
});
diff --git a/llvm/include/llvm/Bitcode/BitcodeReader.h b/llvm/include/llvm/Bitcode/BitcodeReader.h
index 6b4e027..a4b300d 100644
--- a/llvm/include/llvm/Bitcode/BitcodeReader.h
+++ b/llvm/include/llvm/Bitcode/BitcodeReader.h
@@ -34,7 +34,11 @@ class Module;
class MemoryBuffer;
class ModuleSummaryIndex;
-typedef llvm::function_ref<std::optional<std::string>(StringRef)>
+// Callback to override the data layout string of an imported bitcode module.
+// The first argument is the target triple, the second argument the data layout
+// string from the input, or a default string. It will be used if the callback
+// returns std::nullopt.
+typedef llvm::function_ref<std::optional<std::string>(StringRef, StringRef)>
DataLayoutCallbackTy;
// These functions are for converting Expected/Error values to
@@ -101,14 +105,18 @@ typedef llvm::function_ref<std::optional<std::string>(StringRef)>
/// bodies. If ShouldLazyLoadMetadata is true, lazily load metadata as well.
/// If IsImporting is true, this module is being parsed for ThinLTO
/// importing into another module.
- Expected<std::unique_ptr<Module>> getLazyModule(LLVMContext &Context,
- bool ShouldLazyLoadMetadata,
- bool IsImporting);
+ Expected<std::unique_ptr<Module>> getLazyModule(
+ LLVMContext &Context, bool ShouldLazyLoadMetadata, bool IsImporting,
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef, StringRef) {
+ return std::nullopt;
+ });
/// Read the entire bitcode module and return it.
Expected<std::unique_ptr<Module>> parseModule(
- LLVMContext &Context, DataLayoutCallbackTy DataLayoutCallback =
- [](StringRef) { return std::nullopt; });
+ LLVMContext &Context,
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef, StringRef) {
+ return std::nullopt;
+ });
/// Returns information about the module to be used for LTO: whether to
/// compile with ThinLTO, and whether it has a summary.
@@ -145,10 +153,12 @@ typedef llvm::function_ref<std::optional<std::string>(StringRef)>
/// deserialization of function bodies. If ShouldLazyLoadMetadata is true,
/// lazily load metadata as well. If IsImporting is true, this module is
/// being parsed for ThinLTO importing into another module.
- Expected<std::unique_ptr<Module>>
- getLazyBitcodeModule(MemoryBufferRef Buffer, LLVMContext &Context,
- bool ShouldLazyLoadMetadata = false,
- bool IsImporting = false);
+ Expected<std::unique_ptr<Module>> getLazyBitcodeModule(
+ MemoryBufferRef Buffer, LLVMContext &Context,
+ bool ShouldLazyLoadMetadata = false, bool IsImporting = false,
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef, StringRef) {
+ return std::nullopt;
+ });
/// Like getLazyBitcodeModule, except that the module takes ownership of
/// the memory buffer if successful. If successful, this moves Buffer. On
@@ -175,7 +185,7 @@ typedef llvm::function_ref<std::optional<std::string>(StringRef)>
/// Read the specified bitcode file, returning the module.
Expected<std::unique_ptr<Module>> parseBitcodeFile(
MemoryBufferRef Buffer, LLVMContext &Context,
- DataLayoutCallbackTy DataLayoutCallback = [](StringRef) {
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef, StringRef) {
return std::nullopt;
});
diff --git a/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h b/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h
index 1f94f77..e1606e7 100644
--- a/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h
+++ b/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h
@@ -34,7 +34,7 @@ class MachineModuleInfo;
class SMDiagnostic;
class StringRef;
-typedef llvm::function_ref<std::optional<std::string>(StringRef)>
+typedef llvm::function_ref<std::optional<std::string>(StringRef, StringRef)>
DataLayoutCallbackTy;
/// This class initializes machine functions by applying the state loaded from
@@ -52,9 +52,8 @@ public:
/// A new, empty module is created if the LLVM IR isn't present.
/// \returns nullptr if a parsing error occurred.
std::unique_ptr<Module>
- parseIRModule(DataLayoutCallbackTy DataLayoutCallback = [](StringRef) {
- return std::nullopt;
- });
+ parseIRModule(DataLayoutCallbackTy DataLayoutCallback =
+ [](StringRef, StringRef) { return std::nullopt; });
/// Parses MachineFunctions in the MIR file and add them to the given
/// MachineModuleInfo \p MMI.
diff --git a/llvm/include/llvm/IRReader/IRReader.h b/llvm/include/llvm/IRReader/IRReader.h
index 64ddba3..4eabf47 100644
--- a/llvm/include/llvm/IRReader/IRReader.h
+++ b/llvm/include/llvm/IRReader/IRReader.h
@@ -27,7 +27,7 @@ class Module;
class SMDiagnostic;
class LLVMContext;
-typedef llvm::function_ref<std::optional<std::string>(StringRef)>
+typedef llvm::function_ref<std::optional<std::string>(StringRef, StringRef)>
DataLayoutCallbackTy;
/// If the given MemoryBuffer holds a bitcode image, return a Module
@@ -55,7 +55,7 @@ getLazyIRFileModule(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context,
/// \param DataLayoutCallback Override datalayout in the llvm assembly.
std::unique_ptr<Module> parseIR(
MemoryBufferRef Buffer, SMDiagnostic &Err, LLVMContext &Context,
- DataLayoutCallbackTy DataLayoutCallback = [](StringRef) {
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef, StringRef) {
return std::nullopt;
});
@@ -65,7 +65,7 @@ std::unique_ptr<Module> parseIR(
/// \param DataLayoutCallback Override datalayout in the llvm assembly.
std::unique_ptr<Module> parseIRFile(
StringRef Filename, SMDiagnostic &Err, LLVMContext &Context,
- DataLayoutCallbackTy DataLayoutCallback = [](StringRef) {
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef, StringRef) {
return std::nullopt;
});
}
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 435f4bf..8cdf306 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -95,11 +95,8 @@ bool LLParser::Run(bool UpgradeDebugInfo,
"Can't read textual IR with a Context that discards named Values");
if (M) {
- if (parseTargetDefinitions())
+ if (parseTargetDefinitions(DataLayoutCallback))
return true;
-
- if (auto LayoutOverride = DataLayoutCallback(M->getTargetTriple()))
- M->setDataLayout(*LayoutOverride);
}
return parseTopLevelEntities() || validateEndOfModule(UpgradeDebugInfo) ||
@@ -353,11 +350,19 @@ bool LLParser::validateEndOfIndex() {
// Top-Level Entities
//===----------------------------------------------------------------------===//
-bool LLParser::parseTargetDefinitions() {
- while (true) {
+bool LLParser::parseTargetDefinitions(DataLayoutCallbackTy DataLayoutCallback) {
+ // Delay parsing of the data layout string until the target triple is known.
+ // Then, pass both the the target triple and the tentative data layout string
+ // to DataLayoutCallback, allowing to override the DL string.
+ // This enables importing modules with invalid DL strings.
+ std::string TentativeDLStr = M->getDataLayoutStr();
+ LocTy DLStrLoc;
+
+ bool Done = false;
+ while (!Done) {
switch (Lex.getKind()) {
case lltok::kw_target:
- if (parseTargetDefinition())
+ if (parseTargetDefinition(TentativeDLStr, DLStrLoc))
return true;
break;
case lltok::kw_source_filename:
@@ -365,9 +370,21 @@ bool LLParser::parseTargetDefinitions() {
return true;
break;
default:
- return false;
+ Done = true;
}
}
+ // Run the override callback to potentially change the data layout string, and
+ // parse the data layout string.
+ if (auto LayoutOverride =
+ DataLayoutCallback(M->getTargetTriple(), TentativeDLStr)) {
+ TentativeDLStr = *LayoutOverride;
+ DLStrLoc = {};
+ }
+ Expected<DataLayout> MaybeDL = DataLayout::parse(TentativeDLStr);
+ if (!MaybeDL)
+ return error(DLStrLoc, toString(MaybeDL.takeError()));
+ M->setDataLayout(MaybeDL.get());
+ return false;
}
bool LLParser::parseTopLevelEntities() {
@@ -471,7 +488,8 @@ bool LLParser::parseModuleAsm() {
/// toplevelentity
/// ::= 'target' 'triple' '=' STRINGCONSTANT
/// ::= 'target' 'datalayout' '=' STRINGCONSTANT
-bool LLParser::parseTargetDefinition() {
+bool LLParser::parseTargetDefinition(std::string &TentativeDLStr,
+ LocTy &DLStrLoc) {
assert(Lex.getKind() == lltok::kw_target);
std::string Str;
switch (Lex.Lex()) {
@@ -488,13 +506,9 @@ bool LLParser::parseTargetDefinition() {
Lex.Lex();
if (parseToken(lltok::equal, "expected '=' after target datalayout"))
return true;
- LocTy Loc = Lex.getLoc();
- if (parseStringConstant(Str))
+ DLStrLoc = Lex.getLoc();
+ if (parseStringConstant(TentativeDLStr))
return true;
- Expected<DataLayout> MaybeDL = DataLayout::parse(Str);
- if (!MaybeDL)
- return error(Loc, toString(MaybeDL.takeError()));
- M->setDataLayout(MaybeDL.get());
return false;
}
}
diff --git a/llvm/lib/AsmParser/Parser.cpp b/llvm/lib/AsmParser/Parser.cpp
index 5df7789..035eea8 100644
--- a/llvm/lib/AsmParser/Parser.cpp
+++ b/llvm/lib/AsmParser/Parser.cpp
@@ -91,9 +91,10 @@ ParsedModuleAndIndex llvm::parseAssemblyWithIndex(MemoryBufferRef F,
SMDiagnostic &Err,
LLVMContext &Context,
SlotMapping *Slots) {
- return ::parseAssemblyWithIndex(F, Err, Context, Slots,
- /*UpgradeDebugInfo*/ true,
- [](StringRef) { return std::nullopt; });
+ return ::parseAssemblyWithIndex(
+ F, Err, Context, Slots,
+ /*UpgradeDebugInfo*/ true,
+ [](StringRef, StringRef) { return std::nullopt; });
}
static ParsedModuleAndIndex
@@ -150,7 +151,7 @@ static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F,
// index, but we need to initialize it.
LLVMContext unusedContext;
return LLParser(F.getBuffer(), SM, Err, nullptr, &Index, unusedContext)
- .Run(true, [](StringRef) { return std::nullopt; });
+ .Run(true, [](StringRef, StringRef) { return std::nullopt; });
}
std::unique_ptr<ModuleSummaryIndex>
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index cf5027d..aa33006 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -821,7 +821,7 @@ private:
Error parseAttrKind(uint64_t Code, Attribute::AttrKind *Kind);
Error parseModule(
uint64_t ResumeBit, bool ShouldLazyLoadMetadata = false,
- DataLayoutCallbackTy DataLayoutCallback = [](StringRef) {
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef, StringRef) {
return std::nullopt;
});
@@ -4192,21 +4192,35 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
// Parts of bitcode parsing depend on the datalayout. Make sure we
// finalize the datalayout before we run any of that code.
bool ResolvedDataLayout = false;
- auto ResolveDataLayout = [&] {
+ // In order to support importing modules with illegal data layout strings,
+ // delay parsing the data layout string until after upgrades and overrides
+ // have been applied, allowing to fix illegal data layout strings.
+ // Initialize to the current module's layout string in case none is specified.
+ std::string TentativeDataLayoutStr = TheModule->getDataLayoutStr();
+
+ auto ResolveDataLayout = [&]() -> Error {
if (ResolvedDataLayout)
- return;
+ return Error::success();
- // datalayout and triple can't be parsed after this point.
+ // Datalayout and triple can't be parsed after this point.
ResolvedDataLayout = true;
- // Upgrade data layout string.
- std::string DL = llvm::UpgradeDataLayoutString(
- TheModule->getDataLayoutStr(), TheModule->getTargetTriple());
- TheModule->setDataLayout(DL);
+ // Auto-upgrade the layout string
+ TentativeDataLayoutStr = llvm::UpgradeDataLayoutString(
+ TentativeDataLayoutStr, TheModule->getTargetTriple());
+
+ // Apply override
+ if (auto LayoutOverride = DataLayoutCallback(TheModule->getTargetTriple(),
+ TentativeDataLayoutStr))
+ TentativeDataLayoutStr = *LayoutOverride;
+
+ // Now the layout string is finalized in TentativeDataLayoutStr. Parse it.
+ Expected<DataLayout> MaybeDL = DataLayout::parse(TentativeDataLayoutStr);
+ if (!MaybeDL)
+ return MaybeDL.takeError();
- if (auto LayoutOverride =
- DataLayoutCallback(TheModule->getTargetTriple()))
- TheModule->setDataLayout(*LayoutOverride);
+ TheModule->setDataLayout(MaybeDL.get());
+ return Error::success();
};
// Read all the records for this module.
@@ -4220,7 +4234,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
case BitstreamEntry::Error:
return error("Malformed block");
case BitstreamEntry::EndBlock:
- ResolveDataLayout();
+ if (Error Err = ResolveDataLayout())
+ return Err;
return globalCleanup();
case BitstreamEntry::SubBlock:
@@ -4285,7 +4300,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
return Err;
break;
case bitc::FUNCTION_BLOCK_ID:
- ResolveDataLayout();
+ if (Error Err = ResolveDataLayout())
+ return Err;
// If this is the first function body we've seen, reverse the
// FunctionsWithBodies list.
@@ -4384,13 +4400,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
case bitc::MODULE_CODE_DATALAYOUT: { // DATALAYOUT: [strchr x N]
if (ResolvedDataLayout)
return error("datalayout too late in module");
- std::string S;
- if (convertToString(Record, 0, S))
+ if (convertToString(Record, 0, TentativeDataLayoutStr))
return error("Invalid record");
- Expected<DataLayout> MaybeDL = DataLayout::parse(S);
- if (!MaybeDL)
- return MaybeDL.takeError();
- TheModule->setDataLayout(MaybeDL.get());
break;
}
case bitc::MODULE_CODE_ASM: { // ASM: [strchr x N]
@@ -4436,7 +4447,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
return Err;
break;
case bitc::MODULE_CODE_FUNCTION:
- ResolveDataLayout();
+ if (Error Err = ResolveDataLayout())
+ return Err;
if (Error Err = parseFunctionRecord(Record))
return Err;
break;
@@ -4465,6 +4477,7 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
}
Record.clear();
}
+ return Error::success();
}
Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata,
@@ -7946,9 +7959,10 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll,
Expected<std::unique_ptr<Module>>
BitcodeModule::getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata,
- bool IsImporting) {
+ bool IsImporting,
+ DataLayoutCallbackTy DataLayoutCallback) {
return getModuleImpl(Context, false, ShouldLazyLoadMetadata, IsImporting,
- [](StringRef) { return std::nullopt; });
+ DataLayoutCallback);
}
// Parse the specified bitcode buffer and merge the index into CombinedIndex.
@@ -8094,12 +8108,14 @@ static Expected<BitcodeModule> getSingleModule(MemoryBufferRef Buffer) {
Expected<std::unique_ptr<Module>>
llvm::getLazyBitcodeModule(MemoryBufferRef Buffer, LLVMContext &Context,
- bool ShouldLazyLoadMetadata, bool IsImporting) {
+ bool ShouldLazyLoadMetadata, bool IsImporting,
+ DataLayoutCallbackTy DataLayoutCallback) {
Expected<BitcodeModule> BM = getSingleModule(Buffer);
if (!BM)
return BM.takeError();
- return BM->getLazyModule(Context, ShouldLazyLoadMetadata, IsImporting);
+ return BM->getLazyModule(Context, ShouldLazyLoadMetadata, IsImporting,
+ DataLayoutCallback);
}
Expected<std::unique_ptr<Module>> llvm::getOwningLazyBitcodeModule(
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 1cc3cfa..f13116e 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -234,7 +234,8 @@ MIRParserImpl::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) {
// Create an empty module when the MIR file is empty.
NoMIRDocuments = true;
auto M = std::make_unique<Module>(Filename, Context);
- if (auto LayoutOverride = DataLayoutCallback(M->getTargetTriple()))
+ if (auto LayoutOverride =
+ DataLayoutCallback(M->getTargetTriple(), M->getDataLayoutStr()))
M->setDataLayout(*LayoutOverride);
return M;
}
@@ -257,7 +258,8 @@ MIRParserImpl::parseIRModule(DataLayoutCallbackTy DataLayoutCallback) {
} else {
// Create an new, empty module.
M = std::make_unique<Module>(Filename, Context);
- if (auto LayoutOverride = DataLayoutCallback(M->getTargetTriple()))
+ if (auto LayoutOverride =
+ DataLayoutCallback(M->getTargetTriple(), M->getDataLayoutStr()))
M->setDataLayout(*LayoutOverride);
NoLLVMIR = true;
}
diff --git a/llvm/test/Assembler/invalid-datalayout-override.ll b/llvm/test/Assembler/invalid-datalayout-override.ll
new file mode 100644
index 0000000..f62777c
--- /dev/null
+++ b/llvm/test/Assembler/invalid-datalayout-override.ll
@@ -0,0 +1,7 @@
+; Check that importing this file gives an error due to the broken data layout:
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+; Check that specifying a valid data layout allows to import this file:
+; RUN: llvm-as -data-layout "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" < %s
+
+target datalayout = "A16777216"
+; CHECK: Invalid address space, must be a 24-bit integer
diff --git a/llvm/test/Bitcode/function-default-address-spaces.ll b/llvm/test/Bitcode/function-default-address-spaces.ll
index 72b7279..3aae5db 100644
--- a/llvm/test/Bitcode/function-default-address-spaces.ll
+++ b/llvm/test/Bitcode/function-default-address-spaces.ll
@@ -1,7 +1,7 @@
; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s -check-prefixes CHECK,PROG-AS0
; RUN: llvm-as -data-layout "P200" %s -o - | llvm-dis | FileCheck %s -check-prefixes CHECK,PROG-AS200
-; RUN: not --crash llvm-as -data-layout "P123456789" %s -o /dev/null 2>&1 | FileCheck %s -check-prefix BAD-DATALAYOUT
-; BAD-DATALAYOUT: LLVM ERROR: Invalid address space, must be a 24-bit integer
+; RUN: not llvm-as -data-layout "P123456789" %s -o /dev/null 2>&1 | FileCheck %s -check-prefix BAD-DATALAYOUT
+; BAD-DATALAYOUT: error: Invalid address space, must be a 24-bit integer
; PROG-AS0-NOT: target datalayout
; PROG-AS200: target datalayout = "P200"
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index c871d55..d59b128 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -530,8 +530,8 @@ static int compileModule(char **argv, LLVMContext &Context) {
// If user just wants to list available options, skip module loading
if (!SkipModule) {
- auto SetDataLayout =
- [&](StringRef DataLayoutTargetTriple) -> std::optional<std::string> {
+ auto SetDataLayout = [&](StringRef DataLayoutTargetTriple,
+ StringRef OldDLStr) -> std::optional<std::string> {
// If we are supposed to override the target triple, do so now.
std::string IRTargetTriple = DataLayoutTargetTriple.str();
if (!TargetTriple.empty())
diff --git a/llvm/tools/llvm-as/llvm-as.cpp b/llvm/tools/llvm-as/llvm-as.cpp
index e6d4780..ef1c50fc 100644
--- a/llvm/tools/llvm-as/llvm-as.cpp
+++ b/llvm/tools/llvm-as/llvm-as.cpp
@@ -121,7 +121,7 @@ int main(int argc, char **argv) {
// Parse the file now...
SMDiagnostic Err;
- auto SetDataLayout = [](StringRef) -> std::optional<std::string> {
+ auto SetDataLayout = [](StringRef, StringRef) -> std::optional<std::string> {
if (ClDataLayout.empty())
return std::nullopt;
return ClDataLayout;
diff --git a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
index e86c2ad..a608f6f 100644
--- a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
+++ b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
@@ -407,8 +407,8 @@ parseReducerWorkItem(StringRef ToolName, StringRef Filename, LLVMContext &Ctxt,
std::unique_ptr<MIRParser> MParser =
createMIRParser(std::move(FileOrErr.get()), Ctxt);
- auto SetDataLayout =
- [&](StringRef DataLayoutTargetTriple) -> std::optional<std::string> {
+ auto SetDataLayout = [&](StringRef DataLayoutTargetTriple,
+ StringRef OldDLStr) -> std::optional<std::string> {
// If we are supposed to override the target triple, do so now.
std::string IRTargetTriple = DataLayoutTargetTriple.str();
if (!TargetTriple.empty())
diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp
index aa1fe409..392f060 100644
--- a/llvm/tools/opt/opt.cpp
+++ b/llvm/tools/opt/opt.cpp
@@ -534,7 +534,7 @@ int main(int argc, char **argv) {
std::unique_ptr<ToolOutputFile> RemarksFile = std::move(*RemarksFileOrErr);
// Load the input module...
- auto SetDataLayout = [](StringRef) -> std::optional<std::string> {
+ auto SetDataLayout = [](StringRef, StringRef) -> std::optional<std::string> {
if (ClDataLayout.empty())
return std::nullopt;
return ClDataLayout;
diff --git a/llvm/unittests/AsmParser/AsmParserTest.cpp b/llvm/unittests/AsmParser/AsmParserTest.cpp
index 23a0ded..ee6cd70 100644
--- a/llvm/unittests/AsmParser/AsmParserTest.cpp
+++ b/llvm/unittests/AsmParser/AsmParserTest.cpp
@@ -10,8 +10,10 @@
#include "llvm/AsmParser/Parser.h"
#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
@@ -380,4 +382,39 @@ TEST(AsmParserTest, TypeAtBeginningWithSlotMappingParsing) {
ASSERT_TRUE(Read == 4);
}
+TEST(AsmParserTest, InvalidDataLayoutStringCallback) {
+ LLVMContext Ctx;
+ SMDiagnostic Error;
+ // Note the invalid i8:7 part
+ // Overalign i32 as marker so we can check that indeed this DL was used,
+ // and not some default.
+ StringRef InvalidDLStr =
+ "e-m:e-p:64:64-i8:7-i16:16-i32:64-i64:64-f80:128-n8:16:32:64";
+ StringRef FixedDLStr =
+ "e-m:e-p:64:64-i8:8-i16:16-i32:64-i64:64-f80:128-n8:16:32:64";
+ Expected<DataLayout> ExpectedFixedDL = DataLayout::parse(FixedDLStr);
+ ASSERT_TRUE(!ExpectedFixedDL.takeError());
+ DataLayout FixedDL = ExpectedFixedDL.get();
+ std::string Source = ("target datalayout = \"" + InvalidDLStr + "\"\n").str();
+ MemoryBufferRef SourceBuffer(Source, "<string>");
+
+ // Check that we reject the source without a DL override.
+ SlotMapping Mapping1;
+ auto Mod1 = parseAssembly(SourceBuffer, Error, Ctx, &Mapping1);
+ EXPECT_TRUE(Mod1 == nullptr);
+
+ // Check that we pass the correct DL str to the callback,
+ // that fixing the DL str from the callback works,
+ // and that the resulting module has the correct DL.
+ SlotMapping Mapping2;
+ auto Mod2 = parseAssembly(
+ SourceBuffer, Error, Ctx, &Mapping2,
+ [&](StringRef Triple, StringRef DLStr) -> std::optional<std::string> {
+ EXPECT_EQ(DLStr, InvalidDLStr);
+ return std::string{FixedDLStr};
+ });
+ ASSERT_TRUE(Mod2 != nullptr);
+ EXPECT_EQ(Mod2->getDataLayout(), FixedDL);
+}
+
} // end anonymous namespace