[Mlir-commits] [mlir] c35a4f5 - [mlir][Parser] Fix memory leak when failing to parse a forward declared block
River Riddle
llvmlistbot at llvm.org
Mon Jul 25 17:30:04 PDT 2022
Author: River Riddle
Date: 2022-07-25T17:29:49-07:00
New Revision: c35a4f58045ad39faf40b27b57bf52e9a267c019
URL: https://github.com/llvm/llvm-project/commit/c35a4f58045ad39faf40b27b57bf52e9a267c019
DIFF: https://github.com/llvm/llvm-project/commit/c35a4f58045ad39faf40b27b57bf52e9a267c019.diff
LOG: [mlir][Parser] Fix memory leak when failing to parse a forward declared block
This commit fixes a failure edge case where we accidentally drop forward
declared blocks in the error case. This allows for running the
invalid.mlir test in asan mode now.
Fixes #51387
Differential Revision: https://reviews.llvm.org/D130132
Added:
Modified:
mlir/lib/AsmParser/Parser.cpp
mlir/test/IR/invalid.mlir
Removed:
################################################################################
diff --git a/mlir/lib/AsmParser/Parser.cpp b/mlir/lib/AsmParser/Parser.cpp
index 7b17125befec0..9934ca529f7aa 100644
--- a/mlir/lib/AsmParser/Parser.cpp
+++ b/mlir/lib/AsmParser/Parser.cpp
@@ -2090,6 +2090,10 @@ ParseResult OperationParser::parseBlock(Block *&block) {
// only in the case of a successful parse. This ensures that the Block
// allocated is released if the parse fails and control returns early.
std::unique_ptr<Block> inflightBlock;
+ auto cleanupOnFailure = llvm::make_scope_exit([&] {
+ if (inflightBlock)
+ inflightBlock->dropAllDefinedValueUses();
+ });
// If a block has yet to be set, this is a new definition. If the caller
// provided a block, use it. Otherwise create a new one.
@@ -2107,25 +2111,31 @@ ParseResult OperationParser::parseBlock(Block *&block) {
// was already defined.
} else if (!eraseForwardRef(blockAndLoc.block)) {
return emitError(nameLoc, "redefinition of block '") << name << "'";
+ } else {
+ // This was a forward reference block that is now floating. Keep track of it
+ // as inflight in case of error, so that it gets cleaned up properly.
+ inflightBlock.reset(blockAndLoc.block);
}
// Populate the high level assembly state if necessary.
if (state.asmState)
state.asmState->addDefinition(blockAndLoc.block, nameLoc);
-
block = blockAndLoc.block;
// If an argument list is present, parse it.
if (getToken().is(Token::l_paren))
if (parseOptionalBlockArgList(block))
return failure();
-
if (parseToken(Token::colon, "expected ':' after block name"))
return failure();
+ // Parse the body of the block.
ParseResult res = parseBlockBody(block);
+
+ // If parsing was successful, drop the inflight block. We relinquish ownership
+ // back up to the caller.
if (succeeded(res))
- inflightBlock.release();
+ (void)inflightBlock.release();
return res;
}
diff --git a/mlir/test/IR/invalid.mlir b/mlir/test/IR/invalid.mlir
index 0bd39f62a03b0..064b2ed6f749f 100644
--- a/mlir/test/IR/invalid.mlir
+++ b/mlir/test/IR/invalid.mlir
@@ -1,10 +1,6 @@
// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -verify-diagnostics
-// See http://llvm.org/pr52045
-// UNSUPPORTED: asan
-
// Check
diff erent error cases.
-// -----
func.func @bad_branch() {
^bb12:
More information about the Mlir-commits
mailing list