Skip to content

[mlir-tblgen] trim method body to empty with only spaces to avoid crash #139568

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

fengxie
Copy link
Contributor

@fengxie fengxie commented May 12, 2025

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.

    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.

@llvmbot llvmbot added the mlir label May 12, 2025
@llvmbot
Copy link
Member

llvmbot commented May 12, 2025

@llvm/pr-subscribers-mlir

Author: drazi (fengxie)

Changes

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.

    InterfaceMethod&lt;
      ...
      /*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.


Full diff: https://github.com/llvm/llvm-project/pull/139568.diff

2 Files Affected:

  • (modified) mlir/lib/TableGen/Interfaces.cpp (+6)
  • (added) mlir/test/mlir-tblgen/method-body-with-only-spaces.td (+45)
diff --git a/mlir/lib/TableGen/Interfaces.cpp b/mlir/lib/TableGen/Interfaces.cpp
index a209b003b0f3b..9e9d4e4d3b13a 100644
--- a/mlir/lib/TableGen/Interfaces.cpp
+++ b/mlir/lib/TableGen/Interfaces.cpp
@@ -47,12 +47,18 @@ bool InterfaceMethod::isStatic() const {
 // Return the body for this method if it has one.
 std::optional<StringRef> InterfaceMethod::getBody() const {
   auto value = def->getValueAsString("body");
+  // Trim leading and trailing spaces from the default implementation.
+  if (!value.empty())
+    value = value.trim();
   return value.empty() ? std::optional<StringRef>() : value;
 }
 
 // Return the default implementation for this method if it has one.
 std::optional<StringRef> InterfaceMethod::getDefaultImplementation() const {
   auto value = def->getValueAsString("defaultBody");
+  // Trim leading and trailing spaces from the default implementation.
+  if (!value.empty())
+    value = value.trim();
   return value.empty() ? std::optional<StringRef>() : value;
 }
 
diff --git a/mlir/test/mlir-tblgen/method-body-with-only-spaces.td b/mlir/test/mlir-tblgen/method-body-with-only-spaces.td
new file mode 100644
index 0000000000000..daa0067e062d5
--- /dev/null
+++ b/mlir/test/mlir-tblgen/method-body-with-only-spaces.td
@@ -0,0 +1,45 @@
+// RUN: mlir-tblgen --gen-type-interface-decls -I %S/../../include %s | FileCheck %s
+
+include "mlir/IR/OpBase.td"
+
+def TestEmptyMethodBodyTypeInterface : TypeInterface<"TestEmptyMethodBodyTypeInterface"> {
+  let cppNamespace = "::TestEmptyMethodBodyTypeInterface";
+  let description = [{
+    Treat method body with only spaces as empty.
+  }];
+  let methods = [
+    InterfaceMethod<
+      /*desc=*/        [{ Trim spaces of method body and default implementation }],
+      /*returnType=*/  "StringRef",
+      /*methodName=*/  "trimSpaces",
+      /*args=*/        (ins),
+      // CHECK-LABEL: StringRef detail::TestEmptyMethodBodyTypeInterfaceInterfaceTraits::Model<ConcreteType>::trimSpaces
+      // CHECK-SAME: {
+      // CHECK-NEXT: return (::llvm::cast<ConcreteType>(tablegen_opaque_val)).trimSpaces();
+      // CHECK-NEXT: }
+      /*methodBody=*/  [{  }],
+      /*defaultImpl=*/ [{ return StringRef(); }]
+    >
+  ];
+}
+
+def TestEmptyDefaultImplTypeInterface : TypeInterface<"TestEmptyDefaultImplTypeInterface"> {
+  let cppNamespace = "::TestEmptyDefaultImplTypeInterface";
+  let description = [{
+    Treat default implementation with only spaces as empty.
+  }];
+
+  let methods = [
+    InterfaceMethod<
+      /*desc=*/        [{ Trim spaces of default implementation }],
+      /*returnType=*/  "StringRef",
+      /*methodName=*/  "trimSpaces",
+      /*args=*/        (ins),
+      /*methodBody=*/  [{ return StringRef(); }],
+      // COM: Don't generate default implementation
+      // CHECK-NOT: StringRef detail::TestEmptyDefaultImplTypeInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteType>::trimSpaces
+      /*defaultImpl=*/ [{
+      }]
+    >
+  ];
+}

@dcaballe dcaballe requested a review from ftynse May 12, 2025 17:14
@joker-eph joker-eph merged commit eea1e50 into llvm:main May 13, 2025
11 checks passed
@fengxie fengxie deleted the users/fengxie/fix-mlir-tblgen-for-empty-method-body branch May 13, 2025 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants