@@ -3584,6 +3584,24 @@ void OpEmitter::genTypeInterfaceMethods() {
35843584 fctx.addSubst (" _ctxt" , " context" );
35853585 body << " ::mlir::Builder odsBuilder(context);\n " ;
35863586
3587+ // Preprocessing stage to verify all accesses to operands are valid.
3588+ int maxAccessedIndex = -1 ;
3589+ for (int i = 0 , e = op.getNumResults (); i != e; ++i) {
3590+ const InferredResultType &infer = op.getInferredResultType (i);
3591+ if (!infer.isArg ())
3592+ continue ;
3593+ Operator::OperandOrAttribute arg =
3594+ op.getArgToOperandOrAttribute (infer.getIndex ());
3595+ if (arg.kind () == Operator::OperandOrAttribute::Kind::Operand) {
3596+ maxAccessedIndex =
3597+ std::max (maxAccessedIndex, arg.operandOrAttributeIndex ());
3598+ }
3599+ }
3600+ if (maxAccessedIndex != -1 ) {
3601+ body << " if (operands.size() <= " << Twine (maxAccessedIndex) << " )\n " ;
3602+ body << " return ::mlir::failure();\n " ;
3603+ }
3604+
35873605 // Process the type inference graph in topological order, starting from types
35883606 // that are always fully-inferred: operands and results with constructible
35893607 // types. The type inference graph here will always be a DAG, so this gives
@@ -3600,7 +3618,8 @@ void OpEmitter::genTypeInterfaceMethods() {
36003618 if (infer.isArg ()) {
36013619 // If this is an operand, just index into operand list to access the
36023620 // type.
3603- auto arg = op.getArgToOperandOrAttribute (infer.getIndex ());
3621+ Operator::OperandOrAttribute arg =
3622+ op.getArgToOperandOrAttribute (infer.getIndex ());
36043623 if (arg.kind () == Operator::OperandOrAttribute::Kind::Operand) {
36053624 typeStr = (" operands[" + Twine (arg.operandOrAttributeIndex ()) +
36063625 " ].getType()" )
0 commit comments