From eccbe6d1226ae6ad44f06532d9427fac50d25b98 Mon Sep 17 00:00:00 2001 From: Ivan Kosarev Date: Fri, 10 Jun 2022 14:18:29 +0100 Subject: [PATCH] [TableGen][CodeEmitterGen] Do not crash on insufficient positional instruction operands. Reviewed By: foad Differential Revision: https://reviews.llvm.org/D126288 --- .../InsufficientPositionalOperands.td | 30 +++++++++++++++++++ llvm/utils/TableGen/CodeEmitterGen.cpp | 19 ++++++------ 2 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 llvm/test/TableGen/InsufficientPositionalOperands.td diff --git a/llvm/test/TableGen/InsufficientPositionalOperands.td b/llvm/test/TableGen/InsufficientPositionalOperands.td new file mode 100644 index 000000000000..5927bf9ce440 --- /dev/null +++ b/llvm/test/TableGen/InsufficientPositionalOperands.td @@ -0,0 +1,30 @@ +// RUN: not llvm-tblgen -gen-emitter -I %p/../../include %s 2>&1 | FileCheck %s + +// Check that TableGen doesn't crash on insufficient positional +// instruction operands. + +include "llvm/Target/Target.td" + +def ArchInstrInfo : InstrInfo { } + +def Arch : Target { + let InstructionSet = ArchInstrInfo; +} + +def Reg : Register<"reg">; + +def Regs : RegisterClass<"foo", [i32], 0, (add Reg)>; + +def foo : Instruction { + bits<3> rd; + bits<3> rs; + + bits<8> Inst; + let Inst{1-0} = 0; + let Inst{4-2} = rd; + let Inst{7-5} = rs; + +// CHECK: Too few operands in record foo (no match for variable rs) + let OutOperandList = (outs Regs:$xd); + let InOperandList = (ins); +} diff --git a/llvm/utils/TableGen/CodeEmitterGen.cpp b/llvm/utils/TableGen/CodeEmitterGen.cpp index 8f96b7ffc279..2b9931b23c11 100644 --- a/llvm/utils/TableGen/CodeEmitterGen.cpp +++ b/llvm/utils/TableGen/CodeEmitterGen.cpp @@ -22,6 +22,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/TableGenBackend.h" #include @@ -118,16 +119,16 @@ AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName, (!NamedOpIndices.empty() && NamedOpIndices.count( CGI.Operands.getSubOperandNumber(NumberedOp).first)))) { ++NumberedOp; + } - if (NumberedOp >= CGI.Operands.back().MIOperandNo + - CGI.Operands.back().MINumOperands) { - errs() << "Too few operands in record " << R->getName() << - " (no match for variable " << VarName << "):\n"; - errs() << *R; - errs() << '\n'; - - return; - } + if (NumberedOp >= + CGI.Operands.back().MIOperandNo + CGI.Operands.back().MINumOperands) { + std::string E; + raw_string_ostream S(E); + S << "Too few operands in record " << R->getName() + << " (no match for variable " << VarName << "):\n"; + S << *R; + PrintFatalError(R, E); } OpIdx = NumberedOp++;