diff options
author | Jeff Epler <jepler@gmail.com> | 2020-03-01 09:40:43 -0600 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2021-05-30 10:38:48 +1000 |
commit | f2dbc9102251f092e93b7c87cd8ffa5e9e5b880b (patch) | |
tree | f1f42bde0323d14ada0f8a057ac2956833a500eb /py/compile.c | |
parent | a60ad3364132b9c4a30b20cd91fd5cd1ac965618 (diff) |
py/compile: Raise an error on async with/for outside an async function.
A simple reproducer is:
async for x in (): x
Before this change, it would cause an assertion error in mpy-cross and
micropython-coverage.
Diffstat (limited to 'py/compile.c')
-rw-r--r-- | py/compile.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/py/compile.c b/py/compile.c index 1182b8b1e..0b02746a5 100644 --- a/py/compile.c +++ b/py/compile.c @@ -1970,13 +1970,23 @@ STATIC void compile_async_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { compile_funcdef(comp, pns0); scope_t *fscope = (scope_t *)pns0->nodes[4]; fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; - } else if (MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_for_stmt) { - // async for - compile_async_for_stmt(comp, pns0); } else { - // async with - assert(MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_with_stmt); - compile_async_with_stmt(comp, pns0); + // async for/with; first verify the scope is a generator + int scope_flags = comp->scope_cur->scope_flags; + if (!(scope_flags & MP_SCOPE_FLAG_GENERATOR)) { + compile_syntax_error(comp, (mp_parse_node_t)pns0, + MP_ERROR_TEXT("async for/with outside async function")); + return; + } + + if (MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_for_stmt) { + // async for + compile_async_for_stmt(comp, pns0); + } else { + // async with + assert(MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_with_stmt); + compile_async_with_stmt(comp, pns0); + } } } #endif |