Verify that ReturnOp only appears within the region of a FuncOp.

The invariants of ReturnOp are directly tied to FuncOp, making ReturnOp invalid in any other context.

PiperOrigin-RevId: 258421200
This commit is contained in:
River Riddle 2019-07-16 12:45:05 -07:00 committed by Mehdi Amini
parent 0002e2964d
commit a4cbe4ebe1
3 changed files with 18 additions and 4 deletions

View File

@ -71,7 +71,11 @@ public:
/// Return the operation that this refers to.
Operation *getOperation() { return state; }
/// Return the closes surrounding parent operation that is of type 'OpTy'.
/// Returns the closest surrounding operation that contains this operation
/// or nullptr if this is a top-level operation.
Operation *getParentOp() { return getOperation()->getParentOp(); }
/// Return the closest surrounding parent operation that is of type 'OpTy'.
template <typename OpTy> OpTy getParentOfType() {
return getOperation()->getParentOfType<OpTy>();
}

View File

@ -1868,9 +1868,9 @@ static void print(OpAsmPrinter *p, ReturnOp op) {
}
static LogicalResult verify(ReturnOp op) {
// TODO(b/137008268): Return op should verify that it is nested directly
// within a function operation.
auto function = op.getParentOfType<FuncOp>();
auto function = dyn_cast_or_null<FuncOp>(op.getParentOp());
if (!function)
return op.emitOpError() << "must be nested within a 'func' region";
// The operand number and types must match the function signature.
const auto &results = function.getType().getResults();

View File

@ -811,3 +811,13 @@ func @std_if_illegal_block_argument(%arg0: i1) {
}, {}): (i1) -> ()
return
}
// -----
func @return_not_in_function() {
"foo.region"() ({
// expected-error@+1 {{must be nested within a 'func' region}}
return
}): () -> ()
return
}