summaryrefslogtreecommitdiff
path: root/py/compile.c
diff options
context:
space:
mode:
authorJeff Epler <jepler@gmail.com>2020-03-01 09:40:43 -0600
committerDamien George <damien@micropython.org>2021-05-30 10:38:48 +1000
commitf2dbc9102251f092e93b7c87cd8ffa5e9e5b880b (patch)
treef1f42bde0323d14ada0f8a057ac2956833a500eb /py/compile.c
parenta60ad3364132b9c4a30b20cd91fd5cd1ac965618 (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.c22
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