Fix ForStmt and StmtBlock destructors.
Comments included are self-explanatory.
PiperOrigin-RevId: 207198873
diff --git a/include/mlir/IR/Statements.h b/include/mlir/IR/Statements.h
index 2ce17f5..c324f72 100644
--- a/include/mlir/IR/Statements.h
+++ b/include/mlir/IR/Statements.h
@@ -200,12 +200,14 @@
AffineConstantExpr *upperBound, AffineConstantExpr *step,
MLIRContext *context);
- // Loop bounds and step are immortal objects and don't need to be deleted.
- // With this dtor, ForStmt needs to inherit from MLValue before it does from
- // StmtBlock since an MLValue can't be destroyed before the StmtBlock is ---
- // the latter has uses for the induction variables, which is actually the
- // MLValue here. FIXME: this dtor.
- ~ForStmt() {}
+ ~ForStmt() {
+ // Loop bounds and step are immortal objects and don't need to be deleted.
+
+ // Explicitly erase statements instead of relying of 'StmtBlock' destructor
+ // since child statements need to be destroyed before the MLValue that this
+ // for stmt represents is destroyed.
+ getStatements().clear();
+ }
AffineConstantExpr *getLowerBound() const { return lowerBound; }
AffineConstantExpr *getUpperBound() const { return upperBound; }
diff --git a/include/mlir/IR/StmtBlock.h b/include/mlir/IR/StmtBlock.h
index fb94e23..609aabb 100644
--- a/include/mlir/IR/StmtBlock.h
+++ b/include/mlir/IR/StmtBlock.h
@@ -40,6 +40,15 @@
IfClause // IfClause
};
+ ~StmtBlock() { clear(); }
+
+ void clear() {
+ // Clear statements in the reverse order so that uses are destroyed
+ // before their defs.
+ while (!empty())
+ statements.pop_back();
+ }
+
StmtBlockKind getStmtBlockKind() const { return kind; }
/// Returns the closest surrounding statement that contains this block or