Skip to content

Commit eea1e50

Browse files
fengxiejoker-eph
andauthored
[mlir-tblgen] trim method body to empty with only spaces to avoid crash (#139568)
method body or default impl must be true empty. Even they contain only spaces, ``mlir-tblgen`` considers they are non-empty and generates invalid code lead to segment fault. It's very hard to debug. ```c++ InterfaceMethod< ... /*methodBody=*/ [{ }], // This must be true empty. Leaving a space here can lead to segment fault which is hard to figure out why /*defaultImpl=*/ [{ ... }] ``` This PR trim spaces when method body or default implementation of interface method is not empty. Now ``mlir-tblgen`` generates valid code even when they contain only spaces. --------- Co-authored-by: Fung Xie <[email protected]> Co-authored-by: Mehdi Amini <[email protected]>
1 parent f92dd00 commit eea1e50

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

mlir/lib/TableGen/Interfaces.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ bool InterfaceMethod::isStatic() const {
5151

5252
// Return the body for this method if it has one.
5353
std::optional<StringRef> InterfaceMethod::getBody() const {
54-
auto value = def->getValueAsString("body");
54+
// Trim leading and trailing spaces from the default implementation.
55+
auto value = def->getValueAsString("body").trim();
5556
return value.empty() ? std::optional<StringRef>() : value;
5657
}
5758

5859
// Return the default implementation for this method if it has one.
5960
std::optional<StringRef> InterfaceMethod::getDefaultImplementation() const {
60-
auto value = def->getValueAsString("defaultBody");
61+
// Trim leading and trailing spaces from the default implementation.
62+
auto value = def->getValueAsString("defaultBody").trim();
6163
return value.empty() ? std::optional<StringRef>() : value;
6264
}
6365

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: mlir-tblgen --gen-type-interface-decls -I %S/../../include %s | FileCheck %s
2+
3+
include "mlir/IR/OpBase.td"
4+
5+
def TestEmptyMethodBodyTypeInterface : TypeInterface<"TestEmptyMethodBodyTypeInterface"> {
6+
let cppNamespace = "::TestEmptyMethodBodyTypeInterface";
7+
let description = [{
8+
Treat method body with only spaces as empty.
9+
}];
10+
let methods = [
11+
InterfaceMethod<
12+
/*desc=*/ [{ Trim spaces of method body and default implementation }],
13+
/*returnType=*/ "StringRef",
14+
/*methodName=*/ "trimSpaces",
15+
/*args=*/ (ins),
16+
// CHECK-LABEL: StringRef detail::TestEmptyMethodBodyTypeInterfaceInterfaceTraits::Model<ConcreteType>::trimSpaces
17+
// CHECK-SAME: {
18+
// CHECK-NEXT: return (::llvm::cast<ConcreteType>(tablegen_opaque_val)).trimSpaces();
19+
// CHECK-NEXT: }
20+
/*methodBody=*/ [{ }],
21+
/*defaultImpl=*/ [{ return StringRef(); }]
22+
>
23+
];
24+
}
25+
26+
def TestEmptyDefaultImplTypeInterface : TypeInterface<"TestEmptyDefaultImplTypeInterface"> {
27+
let cppNamespace = "::TestEmptyDefaultImplTypeInterface";
28+
let description = [{
29+
Treat default implementation with only spaces as empty.
30+
}];
31+
32+
let methods = [
33+
InterfaceMethod<
34+
/*desc=*/ [{ Trim spaces of default implementation }],
35+
/*returnType=*/ "StringRef",
36+
/*methodName=*/ "trimSpaces",
37+
/*args=*/ (ins),
38+
/*methodBody=*/ [{ return StringRef(); }],
39+
// COM: Don't generate default implementation
40+
// CHECK-NOT: StringRef detail::TestEmptyDefaultImplTypeInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteType>::trimSpaces
41+
/*defaultImpl=*/ [{
42+
}]
43+
>
44+
];
45+
}

0 commit comments

Comments
 (0)