diff --git a/mlir/lib/TableGen/Interfaces.cpp b/mlir/lib/TableGen/Interfaces.cpp index f4fa65777f58..6cdacf16fbb6 100644 --- a/mlir/lib/TableGen/Interfaces.cpp +++ b/mlir/lib/TableGen/Interfaces.cpp @@ -9,6 +9,7 @@ #include "mlir/TableGen/Interfaces.h" #include "llvm/ADT/FunctionExtras.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/Twine.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include @@ -30,8 +31,15 @@ InterfaceMethod::InterfaceMethod(const Record *def, std::string uniqueName) : def(def), uniqueName(uniqueName) { const DagInit *args = def->getValueAsDag("arguments"); for (unsigned i = 0, e = args->getNumArgs(); i != e; ++i) { - arguments.push_back({cast(args->getArg(i))->getValue(), - args->getArgNameStr(i)}); + const Init *arg = args->getArg(i); + const auto *strArg = dyn_cast(arg); + if (!strArg) + llvm::PrintFatalError( + def->getLoc(), + "expected string type for interface method argument #" + Twine(i) + + " ('" + args->getArgNameStr(i) + "') in '" + def->getName() + + "', but got '" + arg->getAsString() + "'"); + arguments.push_back({strArg->getValue(), args->getArgNameStr(i)}); } } diff --git a/mlir/test/mlir-tblgen/interface-method-arg-error.td b/mlir/test/mlir-tblgen/interface-method-arg-error.td new file mode 100644 index 000000000000..5bbaa93c1227 --- /dev/null +++ b/mlir/test/mlir-tblgen/interface-method-arg-error.td @@ -0,0 +1,13 @@ +// RUN: not mlir-tblgen -gen-op-interface-decls -I %S/../../include %s 2>&1 | FileCheck %s + +// Test that a non-string argument type in an interface method gives a readable +// error instead of a crash. See https://github.com/llvm/llvm-project/issues/61869 + +include "mlir/IR/OpBase.td" + +def Foo {} + +// CHECK: error: expected string type for interface method argument #0 ('arg') +def Bar : OpInterface<"Bar"> { + let methods = [InterfaceMethod<[{}], "void", "baz", (ins Foo:$arg)>]; +}