gh-122313: Clean up deep recursion guarding code in the compiler (GH-122640)

Add ENTER_RECURSIVE and LEAVE_RECURSIVE macros in ast.c, ast_opt.c and
symtable.c. Remove VISIT_QUIT macro in symtable.c.

The current recursion depth counter only needs to be updated during
normal execution -- all functions should just return an error code
if an error occurs.
This commit is contained in:
Serhiy Storchaka 2024-08-03 12:45:45 +03:00 committed by GitHub
parent fe0a28d850
commit efcd65cd84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 164 additions and 162 deletions

View file

@ -14,6 +14,20 @@ struct validator {
int recursion_limit; /* recursion limit */ int recursion_limit; /* recursion limit */
}; };
#define ENTER_RECURSIVE(ST) \
do { \
if (++(ST)->recursion_depth > (ST)->recursion_limit) { \
PyErr_SetString(PyExc_RecursionError, \
"maximum recursion depth exceeded during compilation"); \
return 0; \
} \
} while(0)
#define LEAVE_RECURSIVE(ST) \
do { \
--(ST)->recursion_depth; \
} while(0)
static int validate_stmts(struct validator *, asdl_stmt_seq *); static int validate_stmts(struct validator *, asdl_stmt_seq *);
static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int); static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int);
static int validate_patterns(struct validator *, asdl_pattern_seq *, int); static int validate_patterns(struct validator *, asdl_pattern_seq *, int);
@ -166,11 +180,7 @@ validate_constant(struct validator *state, PyObject *value)
return 1; return 1;
if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) { if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
if (++state->recursion_depth > state->recursion_limit) { ENTER_RECURSIVE(state);
PyErr_SetString(PyExc_RecursionError,
"maximum recursion depth exceeded during compilation");
return 0;
}
PyObject *it = PyObject_GetIter(value); PyObject *it = PyObject_GetIter(value);
if (it == NULL) if (it == NULL)
@ -195,7 +205,7 @@ validate_constant(struct validator *state, PyObject *value)
} }
Py_DECREF(it); Py_DECREF(it);
--state->recursion_depth; LEAVE_RECURSIVE(state);
return 1; return 1;
} }
@ -213,11 +223,7 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx)
assert(!PyErr_Occurred()); assert(!PyErr_Occurred());
VALIDATE_POSITIONS(exp); VALIDATE_POSITIONS(exp);
int ret = -1; int ret = -1;
if (++state->recursion_depth > state->recursion_limit) { ENTER_RECURSIVE(state);
PyErr_SetString(PyExc_RecursionError,
"maximum recursion depth exceeded during compilation");
return 0;
}
int check_ctx = 1; int check_ctx = 1;
expr_context_ty actual_ctx; expr_context_ty actual_ctx;
@ -398,7 +404,7 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx)
PyErr_SetString(PyExc_SystemError, "unexpected expression"); PyErr_SetString(PyExc_SystemError, "unexpected expression");
ret = 0; ret = 0;
} }
state->recursion_depth--; LEAVE_RECURSIVE(state);
return ret; return ret;
} }
@ -544,11 +550,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok)
assert(!PyErr_Occurred()); assert(!PyErr_Occurred());
VALIDATE_POSITIONS(p); VALIDATE_POSITIONS(p);
int ret = -1; int ret = -1;
if (++state->recursion_depth > state->recursion_limit) { ENTER_RECURSIVE(state);
PyErr_SetString(PyExc_RecursionError,
"maximum recursion depth exceeded during compilation");
return 0;
}
switch (p->kind) { switch (p->kind) {
case MatchValue_kind: case MatchValue_kind:
ret = validate_pattern_match_value(state, p->v.MatchValue.value); ret = validate_pattern_match_value(state, p->v.MatchValue.value);
@ -690,7 +692,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok)
PyErr_SetString(PyExc_SystemError, "unexpected pattern"); PyErr_SetString(PyExc_SystemError, "unexpected pattern");
ret = 0; ret = 0;
} }
state->recursion_depth--; LEAVE_RECURSIVE(state);
return ret; return ret;
} }
@ -725,11 +727,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
assert(!PyErr_Occurred()); assert(!PyErr_Occurred());
VALIDATE_POSITIONS(stmt); VALIDATE_POSITIONS(stmt);
int ret = -1; int ret = -1;
if (++state->recursion_depth > state->recursion_limit) { ENTER_RECURSIVE(state);
PyErr_SetString(PyExc_RecursionError,
"maximum recursion depth exceeded during compilation");
return 0;
}
switch (stmt->kind) { switch (stmt->kind) {
case FunctionDef_kind: case FunctionDef_kind:
ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") && ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") &&
@ -946,7 +944,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
PyErr_SetString(PyExc_SystemError, "unexpected statement"); PyErr_SetString(PyExc_SystemError, "unexpected statement");
ret = 0; ret = 0;
} }
state->recursion_depth--; LEAVE_RECURSIVE(state);
return ret; return ret;
} }

View file

@ -15,6 +15,19 @@ typedef struct {
int recursion_limit; /* recursion limit */ int recursion_limit; /* recursion limit */
} _PyASTOptimizeState; } _PyASTOptimizeState;
#define ENTER_RECURSIVE(ST) \
do { \
if (++(ST)->recursion_depth > (ST)->recursion_limit) { \
PyErr_SetString(PyExc_RecursionError, \
"maximum recursion depth exceeded during compilation"); \
return 0; \
} \
} while(0)
#define LEAVE_RECURSIVE(ST) \
do { \
--(ST)->recursion_depth; \
} while(0)
static int static int
make_const(expr_ty node, PyObject *val, PyArena *arena) make_const(expr_ty node, PyObject *val, PyArena *arena)
@ -708,11 +721,7 @@ astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
static int static int
astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
{ {
if (++state->recursion_depth > state->recursion_limit) { ENTER_RECURSIVE(state);
PyErr_SetString(PyExc_RecursionError,
"maximum recursion depth exceeded during compilation");
return 0;
}
switch (node_->kind) { switch (node_->kind) {
case BoolOp_kind: case BoolOp_kind:
CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values); CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values);
@ -811,7 +820,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
case Name_kind: case Name_kind:
if (node_->v.Name.ctx == Load && if (node_->v.Name.ctx == Load &&
_PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) { _PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) {
state->recursion_depth--; LEAVE_RECURSIVE(state);
return make_const(node_, PyBool_FromLong(!state->optimize), ctx_); return make_const(node_, PyBool_FromLong(!state->optimize), ctx_);
} }
break; break;
@ -824,7 +833,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
// No default case, so the compiler will emit a warning if new expression // No default case, so the compiler will emit a warning if new expression
// kinds are added without being handled here // kinds are added without being handled here
} }
state->recursion_depth--; LEAVE_RECURSIVE(state);;
return 1; return 1;
} }
@ -871,11 +880,7 @@ astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
static int static int
astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
{ {
if (++state->recursion_depth > state->recursion_limit) { ENTER_RECURSIVE(state);
PyErr_SetString(PyExc_RecursionError,
"maximum recursion depth exceeded during compilation");
return 0;
}
switch (node_->kind) { switch (node_->kind) {
case FunctionDef_kind: case FunctionDef_kind:
CALL_SEQ(astfold_type_param, type_param, node_->v.FunctionDef.type_params); CALL_SEQ(astfold_type_param, type_param, node_->v.FunctionDef.type_params);
@ -999,7 +1004,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
// No default case, so the compiler will emit a warning if new statement // No default case, so the compiler will emit a warning if new statement
// kinds are added without being handled here // kinds are added without being handled here
} }
state->recursion_depth--; LEAVE_RECURSIVE(state);
return 1; return 1;
} }
@ -1031,11 +1036,7 @@ astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
// Currently, this is really only used to form complex/negative numeric // Currently, this is really only used to form complex/negative numeric
// constants in MatchValue and MatchMapping nodes // constants in MatchValue and MatchMapping nodes
// We still recurse into all subexpressions and subpatterns anyway // We still recurse into all subexpressions and subpatterns anyway
if (++state->recursion_depth > state->recursion_limit) { ENTER_RECURSIVE(state);
PyErr_SetString(PyExc_RecursionError,
"maximum recursion depth exceeded during compilation");
return 0;
}
switch (node_->kind) { switch (node_->kind) {
case MatchValue_kind: case MatchValue_kind:
CALL(astfold_expr, expr_ty, node_->v.MatchValue.value); CALL(astfold_expr, expr_ty, node_->v.MatchValue.value);
@ -1067,7 +1068,7 @@ astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
// No default case, so the compiler will emit a warning if new pattern // No default case, so the compiler will emit a warning if new pattern
// kinds are added without being handled here // kinds are added without being handled here
} }
state->recursion_depth--; LEAVE_RECURSIVE(state);
return 1; return 1;
} }

View file

@ -1617,17 +1617,17 @@ symtable_enter_type_param_block(struct symtable *st, identifier name,
VISIT_SEQ_TAIL permits the start of an ASDL sequence to be skipped, which is VISIT_SEQ_TAIL permits the start of an ASDL sequence to be skipped, which is
useful if the first node in the sequence requires special treatment. useful if the first node in the sequence requires special treatment.
VISIT_QUIT macro returns the specified value exiting from the function but ENTER_RECURSIVE macro increments the current recursion depth counter.
first adjusts current recursion counter depth. It should be used at the beginning of the recursive function.
*/
#define VISIT_QUIT(ST, X) \ LEAVE_RECURSIVE macro decrements the current recursion depth counter.
return --(ST)->recursion_depth,(X) It should be used at the end of the recursive function.
*/
#define VISIT(ST, TYPE, V) \ #define VISIT(ST, TYPE, V) \
do { \ do { \
if (!symtable_visit_ ## TYPE((ST), (V))) { \ if (!symtable_visit_ ## TYPE((ST), (V))) { \
VISIT_QUIT((ST), 0); \ return 0; \
} \ } \
} while(0) } while(0)
@ -1638,7 +1638,7 @@ symtable_enter_type_param_block(struct symtable *st, identifier name,
for (i = 0; i < asdl_seq_LEN(seq); i++) { \ for (i = 0; i < asdl_seq_LEN(seq); i++) { \
TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
if (!symtable_visit_ ## TYPE((ST), elt)) \ if (!symtable_visit_ ## TYPE((ST), elt)) \
VISIT_QUIT((ST), 0); \ return 0; \
} \ } \
} while(0) } while(0)
@ -1649,7 +1649,7 @@ symtable_enter_type_param_block(struct symtable *st, identifier name,
for (i = (START); i < asdl_seq_LEN(seq); i++) { \ for (i = (START); i < asdl_seq_LEN(seq); i++) { \
TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
if (!symtable_visit_ ## TYPE((ST), elt)) \ if (!symtable_visit_ ## TYPE((ST), elt)) \
VISIT_QUIT((ST), 0); \ return 0; \
} \ } \
} while(0) } while(0)
@ -1661,10 +1661,25 @@ symtable_enter_type_param_block(struct symtable *st, identifier name,
TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
if (!elt) continue; /* can be NULL */ \ if (!elt) continue; /* can be NULL */ \
if (!symtable_visit_ ## TYPE((ST), elt)) \ if (!symtable_visit_ ## TYPE((ST), elt)) \
VISIT_QUIT((ST), 0); \ return 0; \
} \ } \
} while(0) } while(0)
#define ENTER_RECURSIVE(ST) \
do { \
if (++(ST)->recursion_depth > (ST)->recursion_limit) { \
PyErr_SetString(PyExc_RecursionError, \
"maximum recursion depth exceeded during compilation"); \
return 0; \
} \
} while(0)
#define LEAVE_RECURSIVE(ST) \
do { \
--(ST)->recursion_depth; \
} while(0)
static int static int
symtable_record_directive(struct symtable *st, identifier name, _Py_SourceLocation loc) symtable_record_directive(struct symtable *st, identifier name, _Py_SourceLocation loc)
{ {
@ -1737,15 +1752,11 @@ maybe_set_ste_coroutine_for_module(struct symtable *st, stmt_ty s)
static int static int
symtable_visit_stmt(struct symtable *st, stmt_ty s) symtable_visit_stmt(struct symtable *st, stmt_ty s)
{ {
if (++st->recursion_depth > st->recursion_limit) { ENTER_RECURSIVE(st);
PyErr_SetString(PyExc_RecursionError,
"maximum recursion depth exceeded during compilation");
VISIT_QUIT(st, 0);
}
switch (s->kind) { switch (s->kind) {
case FunctionDef_kind: { case FunctionDef_kind: {
if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL, LOCATION(s))) if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL, LOCATION(s)))
VISIT_QUIT(st, 0); return 0;
if (s->v.FunctionDef.args->defaults) if (s->v.FunctionDef.args->defaults)
VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults); VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults);
if (s->v.FunctionDef.args->kw_defaults) if (s->v.FunctionDef.args->kw_defaults)
@ -1761,40 +1772,40 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
s->v.FunctionDef.args->kw_defaults), s->v.FunctionDef.args->kw_defaults),
s->kind, s->kind,
LOCATION(s))) { LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT_SEQ(st, type_param, s->v.FunctionDef.type_params); VISIT_SEQ(st, type_param, s->v.FunctionDef.type_params);
} }
PySTEntryObject *new_ste = ste_new(st, s->v.FunctionDef.name, FunctionBlock, (void *)s, PySTEntryObject *new_ste = ste_new(st, s->v.FunctionDef.name, FunctionBlock, (void *)s,
LOCATION(s)); LOCATION(s));
if (!new_ste) { if (!new_ste) {
VISIT_QUIT(st, 0); return 0;
} }
if (!symtable_visit_annotations(st, s, s->v.FunctionDef.args, if (!symtable_visit_annotations(st, s, s->v.FunctionDef.args,
s->v.FunctionDef.returns, new_ste)) { s->v.FunctionDef.returns, new_ste)) {
Py_DECREF(new_ste); Py_DECREF(new_ste);
VISIT_QUIT(st, 0); return 0;
} }
if (!symtable_enter_existing_block(st, new_ste)) { if (!symtable_enter_existing_block(st, new_ste)) {
Py_DECREF(new_ste); Py_DECREF(new_ste);
VISIT_QUIT(st, 0); return 0;
} }
Py_DECREF(new_ste); Py_DECREF(new_ste);
VISIT(st, arguments, s->v.FunctionDef.args); VISIT(st, arguments, s->v.FunctionDef.args);
VISIT_SEQ(st, stmt, s->v.FunctionDef.body); VISIT_SEQ(st, stmt, s->v.FunctionDef.body);
if (!symtable_exit_block(st)) if (!symtable_exit_block(st))
VISIT_QUIT(st, 0); return 0;
if (asdl_seq_LEN(s->v.FunctionDef.type_params) > 0) { if (asdl_seq_LEN(s->v.FunctionDef.type_params) > 0) {
if (!symtable_exit_block(st)) if (!symtable_exit_block(st))
VISIT_QUIT(st, 0); return 0;
} }
break; break;
} }
case ClassDef_kind: { case ClassDef_kind: {
PyObject *tmp; PyObject *tmp;
if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL, LOCATION(s))) if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL, LOCATION(s)))
VISIT_QUIT(st, 0); return 0;
if (s->v.ClassDef.decorator_list) if (s->v.ClassDef.decorator_list)
VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list); VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list);
tmp = st->st_private; tmp = st->st_private;
@ -1803,42 +1814,42 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
(void *)s->v.ClassDef.type_params, (void *)s->v.ClassDef.type_params,
false, false, s->kind, false, false, s->kind,
LOCATION(s))) { LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
st->st_private = s->v.ClassDef.name; st->st_private = s->v.ClassDef.name;
st->st_cur->ste_mangled_names = PySet_New(NULL); st->st_cur->ste_mangled_names = PySet_New(NULL);
if (!st->st_cur->ste_mangled_names) { if (!st->st_cur->ste_mangled_names) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT_SEQ(st, type_param, s->v.ClassDef.type_params); VISIT_SEQ(st, type_param, s->v.ClassDef.type_params);
} }
VISIT_SEQ(st, expr, s->v.ClassDef.bases); VISIT_SEQ(st, expr, s->v.ClassDef.bases);
if (!check_keywords(st, s->v.ClassDef.keywords)) { if (!check_keywords(st, s->v.ClassDef.keywords)) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT_SEQ(st, keyword, s->v.ClassDef.keywords); VISIT_SEQ(st, keyword, s->v.ClassDef.keywords);
if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
(void *)s, LOCATION(s))) { (void *)s, LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
st->st_private = s->v.ClassDef.name; st->st_private = s->v.ClassDef.name;
if (asdl_seq_LEN(s->v.ClassDef.type_params) > 0) { if (asdl_seq_LEN(s->v.ClassDef.type_params) > 0) {
if (!symtable_add_def(st, &_Py_ID(__type_params__), if (!symtable_add_def(st, &_Py_ID(__type_params__),
DEF_LOCAL, LOCATION(s))) { DEF_LOCAL, LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
_Py_DECLARE_STR(type_params, ".type_params"); _Py_DECLARE_STR(type_params, ".type_params");
if (!symtable_add_def(st, &_Py_STR(type_params), if (!symtable_add_def(st, &_Py_STR(type_params),
USE, LOCATION(s))) { USE, LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
} }
VISIT_SEQ(st, stmt, s->v.ClassDef.body); VISIT_SEQ(st, stmt, s->v.ClassDef.body);
if (!symtable_exit_block(st)) if (!symtable_exit_block(st))
VISIT_QUIT(st, 0); return 0;
if (asdl_seq_LEN(s->v.ClassDef.type_params) > 0) { if (asdl_seq_LEN(s->v.ClassDef.type_params) > 0) {
if (!symtable_exit_block(st)) if (!symtable_exit_block(st))
VISIT_QUIT(st, 0); return 0;
} }
st->st_private = tmp; st->st_private = tmp;
break; break;
@ -1855,24 +1866,24 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
(void *)s->v.TypeAlias.type_params, (void *)s->v.TypeAlias.type_params,
false, false, s->kind, false, false, s->kind,
LOCATION(s))) { LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT_SEQ(st, type_param, s->v.TypeAlias.type_params); VISIT_SEQ(st, type_param, s->v.TypeAlias.type_params);
} }
if (!symtable_enter_block(st, name, TypeAliasBlock, if (!symtable_enter_block(st, name, TypeAliasBlock,
(void *)s, LOCATION(s))) { (void *)s, LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
st->st_cur->ste_can_see_class_scope = is_in_class; st->st_cur->ste_can_see_class_scope = is_in_class;
if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(s->v.TypeAlias.value))) { if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(s->v.TypeAlias.value))) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT(st, expr, s->v.TypeAlias.value); VISIT(st, expr, s->v.TypeAlias.value);
if (!symtable_exit_block(st)) if (!symtable_exit_block(st))
VISIT_QUIT(st, 0); return 0;
if (is_generic) { if (is_generic) {
if (!symtable_exit_block(st)) if (!symtable_exit_block(st))
VISIT_QUIT(st, 0); return 0;
} }
break; break;
} }
@ -1895,7 +1906,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
expr_ty e_name = s->v.AnnAssign.target; expr_ty e_name = s->v.AnnAssign.target;
long cur = symtable_lookup(st, e_name->v.Name.id); long cur = symtable_lookup(st, e_name->v.Name.id);
if (cur < 0) { if (cur < 0) {
VISIT_QUIT(st, 0); return 0;
} }
if ((cur & (DEF_GLOBAL | DEF_NONLOCAL)) if ((cur & (DEF_GLOBAL | DEF_NONLOCAL))
&& (st->st_cur->ste_symbols != st->st_global) && (st->st_cur->ste_symbols != st->st_global)
@ -1904,17 +1915,17 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
cur & DEF_GLOBAL ? GLOBAL_ANNOT : NONLOCAL_ANNOT, cur & DEF_GLOBAL ? GLOBAL_ANNOT : NONLOCAL_ANNOT,
e_name->v.Name.id); e_name->v.Name.id);
SET_ERROR_LOCATION(st->st_filename, LOCATION(s)); SET_ERROR_LOCATION(st->st_filename, LOCATION(s));
VISIT_QUIT(st, 0); return 0;
} }
if (s->v.AnnAssign.simple && if (s->v.AnnAssign.simple &&
!symtable_add_def(st, e_name->v.Name.id, !symtable_add_def(st, e_name->v.Name.id,
DEF_ANNOT | DEF_LOCAL, LOCATION(e_name))) { DEF_ANNOT | DEF_LOCAL, LOCATION(e_name))) {
VISIT_QUIT(st, 0); return 0;
} }
else { else {
if (s->v.AnnAssign.value if (s->v.AnnAssign.value
&& !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL, LOCATION(e_name))) { && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL, LOCATION(e_name))) {
VISIT_QUIT(st, 0); return 0;
} }
} }
} }
@ -1923,7 +1934,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
} }
if (!symtable_visit_annotation(st, s->v.AnnAssign.annotation, if (!symtable_visit_annotation(st, s->v.AnnAssign.annotation,
(void *)((uintptr_t)st->st_cur->ste_id + 1))) { (void *)((uintptr_t)st->st_cur->ste_id + 1))) {
VISIT_QUIT(st, 0); return 0;
} }
if (s->v.AnnAssign.value) { if (s->v.AnnAssign.value) {
@ -1990,7 +2001,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
case ImportFrom_kind: case ImportFrom_kind:
VISIT_SEQ(st, alias, s->v.ImportFrom.names); VISIT_SEQ(st, alias, s->v.ImportFrom.names);
if (!check_import_from(st, s)) { if (!check_import_from(st, s)) {
VISIT_QUIT(st, 0); return 0;
} }
break; break;
case Global_kind: { case Global_kind: {
@ -2000,7 +2011,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
identifier name = (identifier)asdl_seq_GET(seq, i); identifier name = (identifier)asdl_seq_GET(seq, i);
long cur = symtable_lookup(st, name); long cur = symtable_lookup(st, name);
if (cur < 0) if (cur < 0)
VISIT_QUIT(st, 0); return 0;
if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) { if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) {
const char* msg; const char* msg;
if (cur & DEF_PARAM) { if (cur & DEF_PARAM) {
@ -2015,13 +2026,13 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
PyErr_Format(PyExc_SyntaxError, PyErr_Format(PyExc_SyntaxError,
msg, name); msg, name);
SET_ERROR_LOCATION(st->st_filename, LOCATION(s)); SET_ERROR_LOCATION(st->st_filename, LOCATION(s));
VISIT_QUIT(st, 0); return 0;
} }
if (!symtable_add_def(st, name, DEF_GLOBAL, LOCATION(s))) { if (!symtable_add_def(st, name, DEF_GLOBAL, LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
if (!symtable_record_directive(st, name, LOCATION(s))) { if (!symtable_record_directive(st, name, LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
} }
break; break;
@ -2033,7 +2044,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
identifier name = (identifier)asdl_seq_GET(seq, i); identifier name = (identifier)asdl_seq_GET(seq, i);
long cur = symtable_lookup(st, name); long cur = symtable_lookup(st, name);
if (cur < 0) if (cur < 0)
VISIT_QUIT(st, 0); return 0;
if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) { if (cur & (DEF_PARAM | DEF_LOCAL | USE | DEF_ANNOT)) {
const char* msg; const char* msg;
if (cur & DEF_PARAM) { if (cur & DEF_PARAM) {
@ -2047,12 +2058,12 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
} }
PyErr_Format(PyExc_SyntaxError, msg, name); PyErr_Format(PyExc_SyntaxError, msg, name);
SET_ERROR_LOCATION(st->st_filename, LOCATION(s)); SET_ERROR_LOCATION(st->st_filename, LOCATION(s));
VISIT_QUIT(st, 0); return 0;
} }
if (!symtable_add_def(st, name, DEF_NONLOCAL, LOCATION(s))) if (!symtable_add_def(st, name, DEF_NONLOCAL, LOCATION(s)))
VISIT_QUIT(st, 0); return 0;
if (!symtable_record_directive(st, name, LOCATION(s))) { if (!symtable_record_directive(st, name, LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
} }
break; break;
@ -2071,7 +2082,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
break; break;
case AsyncFunctionDef_kind: { case AsyncFunctionDef_kind: {
if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL, LOCATION(s))) if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL, LOCATION(s)))
VISIT_QUIT(st, 0); return 0;
if (s->v.AsyncFunctionDef.args->defaults) if (s->v.AsyncFunctionDef.args->defaults)
VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.args->defaults); VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.args->defaults);
if (s->v.AsyncFunctionDef.args->kw_defaults) if (s->v.AsyncFunctionDef.args->kw_defaults)
@ -2088,24 +2099,24 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
s->v.AsyncFunctionDef.args->kw_defaults), s->v.AsyncFunctionDef.args->kw_defaults),
s->kind, s->kind,
LOCATION(s))) { LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT_SEQ(st, type_param, s->v.AsyncFunctionDef.type_params); VISIT_SEQ(st, type_param, s->v.AsyncFunctionDef.type_params);
} }
PySTEntryObject *new_ste = ste_new(st, s->v.FunctionDef.name, FunctionBlock, (void *)s, PySTEntryObject *new_ste = ste_new(st, s->v.FunctionDef.name, FunctionBlock, (void *)s,
LOCATION(s)); LOCATION(s));
if (!new_ste) { if (!new_ste) {
VISIT_QUIT(st, 0); return 0;
} }
if (!symtable_visit_annotations(st, s, s->v.AsyncFunctionDef.args, if (!symtable_visit_annotations(st, s, s->v.AsyncFunctionDef.args,
s->v.AsyncFunctionDef.returns, new_ste)) { s->v.AsyncFunctionDef.returns, new_ste)) {
Py_DECREF(new_ste); Py_DECREF(new_ste);
VISIT_QUIT(st, 0); return 0;
} }
if (!symtable_enter_existing_block(st, new_ste)) { if (!symtable_enter_existing_block(st, new_ste)) {
Py_DECREF(new_ste); Py_DECREF(new_ste);
VISIT_QUIT(st, 0); return 0;
} }
Py_DECREF(new_ste); Py_DECREF(new_ste);
@ -2113,17 +2124,17 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
VISIT(st, arguments, s->v.AsyncFunctionDef.args); VISIT(st, arguments, s->v.AsyncFunctionDef.args);
VISIT_SEQ(st, stmt, s->v.AsyncFunctionDef.body); VISIT_SEQ(st, stmt, s->v.AsyncFunctionDef.body);
if (!symtable_exit_block(st)) if (!symtable_exit_block(st))
VISIT_QUIT(st, 0); return 0;
if (asdl_seq_LEN(s->v.AsyncFunctionDef.type_params) > 0) { if (asdl_seq_LEN(s->v.AsyncFunctionDef.type_params) > 0) {
if (!symtable_exit_block(st)) if (!symtable_exit_block(st))
VISIT_QUIT(st, 0); return 0;
} }
break; break;
} }
case AsyncWith_kind: case AsyncWith_kind:
maybe_set_ste_coroutine_for_module(st, s); maybe_set_ste_coroutine_for_module(st, s);
if (!symtable_raise_if_not_coroutine(st, ASYNC_WITH_OUTSIDE_ASYNC_FUNC, LOCATION(s))) { if (!symtable_raise_if_not_coroutine(st, ASYNC_WITH_OUTSIDE_ASYNC_FUNC, LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT_SEQ(st, withitem, s->v.AsyncWith.items); VISIT_SEQ(st, withitem, s->v.AsyncWith.items);
VISIT_SEQ(st, stmt, s->v.AsyncWith.body); VISIT_SEQ(st, stmt, s->v.AsyncWith.body);
@ -2131,7 +2142,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
case AsyncFor_kind: case AsyncFor_kind:
maybe_set_ste_coroutine_for_module(st, s); maybe_set_ste_coroutine_for_module(st, s);
if (!symtable_raise_if_not_coroutine(st, ASYNC_FOR_OUTSIDE_ASYNC_FUNC, LOCATION(s))) { if (!symtable_raise_if_not_coroutine(st, ASYNC_FOR_OUTSIDE_ASYNC_FUNC, LOCATION(s))) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT(st, expr, s->v.AsyncFor.target); VISIT(st, expr, s->v.AsyncFor.target);
VISIT(st, expr, s->v.AsyncFor.iter); VISIT(st, expr, s->v.AsyncFor.iter);
@ -2140,7 +2151,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
VISIT_SEQ(st, stmt, s->v.AsyncFor.orelse); VISIT_SEQ(st, stmt, s->v.AsyncFor.orelse);
break; break;
} }
VISIT_QUIT(st, 1); LEAVE_RECURSIVE(st);
return 1;
} }
static int static int
@ -2168,7 +2180,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
(target_in_scope & DEF_LOCAL)) { (target_in_scope & DEF_LOCAL)) {
PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name); PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name);
SET_ERROR_LOCATION(st->st_filename, LOCATION(e)); SET_ERROR_LOCATION(st->st_filename, LOCATION(e));
VISIT_QUIT(st, 0); return 0;
} }
continue; continue;
} }
@ -2178,14 +2190,14 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
long target_in_scope = symtable_lookup_entry(st, ste, target_name); long target_in_scope = symtable_lookup_entry(st, ste, target_name);
if (target_in_scope & DEF_GLOBAL) { if (target_in_scope & DEF_GLOBAL) {
if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e))) if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e)))
VISIT_QUIT(st, 0); return 0;
} else { } else {
if (!symtable_add_def(st, target_name, DEF_NONLOCAL, LOCATION(e))) { if (!symtable_add_def(st, target_name, DEF_NONLOCAL, LOCATION(e))) {
VISIT_QUIT(st, 0); return 0;
} }
} }
if (!symtable_record_directive(st, target_name, LOCATION(e))) { if (!symtable_record_directive(st, target_name, LOCATION(e))) {
VISIT_QUIT(st, 0); return 0;
} }
return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste, LOCATION(e)); return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste, LOCATION(e));
@ -2193,10 +2205,10 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
/* If we find a ModuleBlock entry, add as GLOBAL */ /* If we find a ModuleBlock entry, add as GLOBAL */
if (ste->ste_type == ModuleBlock) { if (ste->ste_type == ModuleBlock) {
if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e))) { if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e))) {
VISIT_QUIT(st, 0); return 0;
} }
if (!symtable_record_directive(st, target_name, LOCATION(e))) { if (!symtable_record_directive(st, target_name, LOCATION(e))) {
VISIT_QUIT(st, 0); return 0;
} }
return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste, LOCATION(e)); return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste, LOCATION(e));
@ -2223,7 +2235,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
Py_UNREACHABLE(); Py_UNREACHABLE();
} }
SET_ERROR_LOCATION(st->st_filename, LOCATION(e)); SET_ERROR_LOCATION(st->st_filename, LOCATION(e));
VISIT_QUIT(st, 0); return 0;
} }
} }
@ -2256,18 +2268,14 @@ symtable_handle_namedexpr(struct symtable *st, expr_ty e)
static int static int
symtable_visit_expr(struct symtable *st, expr_ty e) symtable_visit_expr(struct symtable *st, expr_ty e)
{ {
if (++st->recursion_depth > st->recursion_limit) { ENTER_RECURSIVE(st);
PyErr_SetString(PyExc_RecursionError,
"maximum recursion depth exceeded during compilation");
VISIT_QUIT(st, 0);
}
switch (e->kind) { switch (e->kind) {
case NamedExpr_kind: case NamedExpr_kind:
if (!symtable_raise_if_annotation_block(st, "named expression", e)) { if (!symtable_raise_if_annotation_block(st, "named expression", e)) {
VISIT_QUIT(st, 0); return 0;
} }
if(!symtable_handle_namedexpr(st, e)) if(!symtable_handle_namedexpr(st, e))
VISIT_QUIT(st, 0); return 0;
break; break;
case BoolOp_kind: case BoolOp_kind:
VISIT_SEQ(st, expr, e->v.BoolOp.values); VISIT_SEQ(st, expr, e->v.BoolOp.values);
@ -2286,12 +2294,12 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults); VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults);
if (!symtable_enter_block(st, &_Py_ID(lambda), if (!symtable_enter_block(st, &_Py_ID(lambda),
FunctionBlock, (void *)e, LOCATION(e))) { FunctionBlock, (void *)e, LOCATION(e))) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT(st, arguments, e->v.Lambda.args); VISIT(st, arguments, e->v.Lambda.args);
VISIT(st, expr, e->v.Lambda.body); VISIT(st, expr, e->v.Lambda.body);
if (!symtable_exit_block(st)) if (!symtable_exit_block(st))
VISIT_QUIT(st, 0); return 0;
break; break;
} }
case IfExp_kind: case IfExp_kind:
@ -2308,23 +2316,23 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
break; break;
case GeneratorExp_kind: case GeneratorExp_kind:
if (!symtable_visit_genexp(st, e)) if (!symtable_visit_genexp(st, e))
VISIT_QUIT(st, 0); return 0;
break; break;
case ListComp_kind: case ListComp_kind:
if (!symtable_visit_listcomp(st, e)) if (!symtable_visit_listcomp(st, e))
VISIT_QUIT(st, 0); return 0;
break; break;
case SetComp_kind: case SetComp_kind:
if (!symtable_visit_setcomp(st, e)) if (!symtable_visit_setcomp(st, e))
VISIT_QUIT(st, 0); return 0;
break; break;
case DictComp_kind: case DictComp_kind:
if (!symtable_visit_dictcomp(st, e)) if (!symtable_visit_dictcomp(st, e))
VISIT_QUIT(st, 0); return 0;
break; break;
case Yield_kind: case Yield_kind:
if (!symtable_raise_if_annotation_block(st, "yield expression", e)) { if (!symtable_raise_if_annotation_block(st, "yield expression", e)) {
VISIT_QUIT(st, 0); return 0;
} }
if (e->v.Yield.value) if (e->v.Yield.value)
VISIT(st, expr, e->v.Yield.value); VISIT(st, expr, e->v.Yield.value);
@ -2335,7 +2343,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
break; break;
case YieldFrom_kind: case YieldFrom_kind:
if (!symtable_raise_if_annotation_block(st, "yield expression", e)) { if (!symtable_raise_if_annotation_block(st, "yield expression", e)) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT(st, expr, e->v.YieldFrom.value); VISIT(st, expr, e->v.YieldFrom.value);
st->st_cur->ste_generator = 1; st->st_cur->ste_generator = 1;
@ -2345,20 +2353,20 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
break; break;
case Await_kind: case Await_kind:
if (!symtable_raise_if_annotation_block(st, "await expression", e)) { if (!symtable_raise_if_annotation_block(st, "await expression", e)) {
VISIT_QUIT(st, 0); return 0;
} }
if (!allows_top_level_await(st)) { if (!allows_top_level_await(st)) {
if (!_PyST_IsFunctionLike(st->st_cur)) { if (!_PyST_IsFunctionLike(st->st_cur)) {
PyErr_SetString(PyExc_SyntaxError, PyErr_SetString(PyExc_SyntaxError,
"'await' outside function"); "'await' outside function");
SET_ERROR_LOCATION(st->st_filename, LOCATION(e)); SET_ERROR_LOCATION(st->st_filename, LOCATION(e));
VISIT_QUIT(st, 0); return 0;
} }
if (!IS_ASYNC_DEF(st) && st->st_cur->ste_comprehension == NoComprehension) { if (!IS_ASYNC_DEF(st) && st->st_cur->ste_comprehension == NoComprehension) {
PyErr_SetString(PyExc_SyntaxError, PyErr_SetString(PyExc_SyntaxError,
"'await' outside async function"); "'await' outside async function");
SET_ERROR_LOCATION(st->st_filename, LOCATION(e)); SET_ERROR_LOCATION(st->st_filename, LOCATION(e));
VISIT_QUIT(st, 0); return 0;
} }
} }
VISIT(st, expr, e->v.Await.value); VISIT(st, expr, e->v.Await.value);
@ -2372,7 +2380,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
VISIT(st, expr, e->v.Call.func); VISIT(st, expr, e->v.Call.func);
VISIT_SEQ(st, expr, e->v.Call.args); VISIT_SEQ(st, expr, e->v.Call.args);
if (!check_keywords(st, e->v.Call.keywords)) { if (!check_keywords(st, e->v.Call.keywords)) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT_SEQ_WITH_NULL(st, keyword, e->v.Call.keywords); VISIT_SEQ_WITH_NULL(st, keyword, e->v.Call.keywords);
break; break;
@ -2390,7 +2398,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
/* The following exprs can be assignment targets. */ /* The following exprs can be assignment targets. */
case Attribute_kind: case Attribute_kind:
if (!check_name(st, e->v.Attribute.attr, LOCATION(e), e->v.Attribute.ctx)) { if (!check_name(st, e->v.Attribute.attr, LOCATION(e), e->v.Attribute.ctx)) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT(st, expr, e->v.Attribute.value); VISIT(st, expr, e->v.Attribute.value);
break; break;
@ -2413,14 +2421,14 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
if (!symtable_add_def_ctx(st, e->v.Name.id, if (!symtable_add_def_ctx(st, e->v.Name.id,
e->v.Name.ctx == Load ? USE : DEF_LOCAL, e->v.Name.ctx == Load ? USE : DEF_LOCAL,
LOCATION(e), e->v.Name.ctx)) { LOCATION(e), e->v.Name.ctx)) {
VISIT_QUIT(st, 0); return 0;
} }
/* Special-case super: it counts as a use of __class__ */ /* Special-case super: it counts as a use of __class__ */
if (e->v.Name.ctx == Load && if (e->v.Name.ctx == Load &&
_PyST_IsFunctionLike(st->st_cur) && _PyST_IsFunctionLike(st->st_cur) &&
_PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) { _PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) {
if (!symtable_add_def(st, &_Py_ID(__class__), USE, LOCATION(e))) if (!symtable_add_def(st, &_Py_ID(__class__), USE, LOCATION(e)))
VISIT_QUIT(st, 0); return 0;
} }
break; break;
/* child nodes of List and Tuple will have expr_context set */ /* child nodes of List and Tuple will have expr_context set */
@ -2431,7 +2439,8 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
VISIT_SEQ(st, expr, e->v.Tuple.elts); VISIT_SEQ(st, expr, e->v.Tuple.elts);
break; break;
} }
VISIT_QUIT(st, 1); LEAVE_RECURSIVE(st);
return 1;
} }
static int static int
@ -2447,7 +2456,7 @@ symtable_visit_type_param_bound_or_default(
st->st_cur->ste_can_see_class_scope = is_in_class; st->st_cur->ste_can_see_class_scope = is_in_class;
if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(e))) { if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(e))) {
VISIT_QUIT(st, 0); return 0;
} }
assert(ste_scope_info != NULL); assert(ste_scope_info != NULL);
@ -2464,15 +2473,11 @@ symtable_visit_type_param_bound_or_default(
static int static int
symtable_visit_type_param(struct symtable *st, type_param_ty tp) symtable_visit_type_param(struct symtable *st, type_param_ty tp)
{ {
if (++st->recursion_depth > st->recursion_limit) { ENTER_RECURSIVE(st);
PyErr_SetString(PyExc_RecursionError,
"maximum recursion depth exceeded during compilation");
VISIT_QUIT(st, 0);
}
switch(tp->kind) { switch(tp->kind) {
case TypeVar_kind: case TypeVar_kind:
if (!symtable_add_def(st, tp->v.TypeVar.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp))) if (!symtable_add_def(st, tp->v.TypeVar.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp)))
VISIT_QUIT(st, 0); return 0;
const char *ste_scope_info = NULL; const char *ste_scope_info = NULL;
const expr_ty bound = tp->v.TypeVar.bound; const expr_ty bound = tp->v.TypeVar.bound;
@ -2488,46 +2493,43 @@ symtable_visit_type_param(struct symtable *st, type_param_ty tp)
// compile.c where the scope is retrieved. // compile.c where the scope is retrieved.
if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVar.bound, tp->v.TypeVar.name, if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVar.bound, tp->v.TypeVar.name,
(void *)tp, ste_scope_info)) { (void *)tp, ste_scope_info)) {
VISIT_QUIT(st, 0); return 0;
} }
if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVar.default_value, tp->v.TypeVar.name, if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVar.default_value, tp->v.TypeVar.name,
(void *)((uintptr_t)tp + 1), "a TypeVar default")) { (void *)((uintptr_t)tp + 1), "a TypeVar default")) {
VISIT_QUIT(st, 0); return 0;
} }
break; break;
case TypeVarTuple_kind: case TypeVarTuple_kind:
if (!symtable_add_def(st, tp->v.TypeVarTuple.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp))) { if (!symtable_add_def(st, tp->v.TypeVarTuple.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp))) {
VISIT_QUIT(st, 0); return 0;
} }
if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVarTuple.default_value, tp->v.TypeVarTuple.name, if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVarTuple.default_value, tp->v.TypeVarTuple.name,
(void *)tp, "a TypeVarTuple default")) { (void *)tp, "a TypeVarTuple default")) {
VISIT_QUIT(st, 0); return 0;
} }
break; break;
case ParamSpec_kind: case ParamSpec_kind:
if (!symtable_add_def(st, tp->v.ParamSpec.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp))) { if (!symtable_add_def(st, tp->v.ParamSpec.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp))) {
VISIT_QUIT(st, 0); return 0;
} }
if (!symtable_visit_type_param_bound_or_default(st, tp->v.ParamSpec.default_value, tp->v.ParamSpec.name, if (!symtable_visit_type_param_bound_or_default(st, tp->v.ParamSpec.default_value, tp->v.ParamSpec.name,
(void *)tp, "a ParamSpec default")) { (void *)tp, "a ParamSpec default")) {
VISIT_QUIT(st, 0); return 0;
} }
break; break;
} }
VISIT_QUIT(st, 1); LEAVE_RECURSIVE(st);
return 1;
} }
static int static int
symtable_visit_pattern(struct symtable *st, pattern_ty p) symtable_visit_pattern(struct symtable *st, pattern_ty p)
{ {
if (++st->recursion_depth > st->recursion_limit) { ENTER_RECURSIVE(st);
PyErr_SetString(PyExc_RecursionError,
"maximum recursion depth exceeded during compilation");
VISIT_QUIT(st, 0);
}
switch (p->kind) { switch (p->kind) {
case MatchValue_kind: case MatchValue_kind:
VISIT(st, expr, p->v.MatchValue.value); VISIT(st, expr, p->v.MatchValue.value);
@ -2541,7 +2543,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
case MatchStar_kind: case MatchStar_kind:
if (p->v.MatchStar.name) { if (p->v.MatchStar.name) {
if (!symtable_add_def(st, p->v.MatchStar.name, DEF_LOCAL, LOCATION(p))) { if (!symtable_add_def(st, p->v.MatchStar.name, DEF_LOCAL, LOCATION(p))) {
VISIT_QUIT(st, 0); return 0;
} }
} }
break; break;
@ -2550,7 +2552,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
VISIT_SEQ(st, pattern, p->v.MatchMapping.patterns); VISIT_SEQ(st, pattern, p->v.MatchMapping.patterns);
if (p->v.MatchMapping.rest) { if (p->v.MatchMapping.rest) {
if (!symtable_add_def(st, p->v.MatchMapping.rest, DEF_LOCAL, LOCATION(p))) { if (!symtable_add_def(st, p->v.MatchMapping.rest, DEF_LOCAL, LOCATION(p))) {
VISIT_QUIT(st, 0); return 0;
} }
} }
break; break;
@ -2558,7 +2560,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
VISIT(st, expr, p->v.MatchClass.cls); VISIT(st, expr, p->v.MatchClass.cls);
VISIT_SEQ(st, pattern, p->v.MatchClass.patterns); VISIT_SEQ(st, pattern, p->v.MatchClass.patterns);
if (!check_kwd_patterns(st, p)) { if (!check_kwd_patterns(st, p)) {
VISIT_QUIT(st, 0); return 0;
} }
VISIT_SEQ(st, pattern, p->v.MatchClass.kwd_patterns); VISIT_SEQ(st, pattern, p->v.MatchClass.kwd_patterns);
break; break;
@ -2568,7 +2570,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
} }
if (p->v.MatchAs.name) { if (p->v.MatchAs.name) {
if (!symtable_add_def(st, p->v.MatchAs.name, DEF_LOCAL, LOCATION(p))) { if (!symtable_add_def(st, p->v.MatchAs.name, DEF_LOCAL, LOCATION(p))) {
VISIT_QUIT(st, 0); return 0;
} }
} }
break; break;
@ -2576,7 +2578,8 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p)
VISIT_SEQ(st, pattern, p->v.MatchOr.patterns); VISIT_SEQ(st, pattern, p->v.MatchOr.patterns);
break; break;
} }
VISIT_QUIT(st, 1); LEAVE_RECURSIVE(st);
return 1;
} }
static int static int
@ -2618,7 +2621,7 @@ symtable_visit_annotation(struct symtable *st, expr_ty annotation, void *key)
_Py_block_ty current_type = parent_ste->ste_type; _Py_block_ty current_type = parent_ste->ste_type;
if (!symtable_enter_block(st, &_Py_ID(__annotate__), AnnotationBlock, if (!symtable_enter_block(st, &_Py_ID(__annotate__), AnnotationBlock,
key, LOCATION(annotation))) { key, LOCATION(annotation))) {
VISIT_QUIT(st, 0); return 0;
} }
parent_ste->ste_annotation_block = parent_ste->ste_annotation_block =
(struct _symtable_entry *)Py_NewRef(st->st_cur); (struct _symtable_entry *)Py_NewRef(st->st_cur);
@ -2632,12 +2635,12 @@ symtable_visit_annotation(struct symtable *st, expr_ty annotation, void *key)
} }
else { else {
if (!symtable_enter_existing_block(st, parent_ste->ste_annotation_block)) { if (!symtable_enter_existing_block(st, parent_ste->ste_annotation_block)) {
VISIT_QUIT(st, 0); return 0;
} }
} }
VISIT(st, expr, annotation); VISIT(st, expr, annotation);
if (!symtable_exit_block(st)) { if (!symtable_exit_block(st)) {
VISIT_QUIT(st, 0); return 0;
} }
return 1; return 1;
} }
@ -2669,7 +2672,7 @@ symtable_visit_annotations(struct symtable *st, stmt_ty o, arguments_ty a, expr_
_Py_block_ty current_type = st->st_cur->ste_type; _Py_block_ty current_type = st->st_cur->ste_type;
if (!symtable_enter_block(st, &_Py_ID(__annotate__), AnnotationBlock, if (!symtable_enter_block(st, &_Py_ID(__annotate__), AnnotationBlock,
(void *)a, LOCATION(o))) { (void *)a, LOCATION(o))) {
VISIT_QUIT(st, 0); return 0;
} }
if (is_in_class || current_type == ClassBlock) { if (is_in_class || current_type == ClassBlock) {
st->st_cur->ste_can_see_class_scope = 1; st->st_cur->ste_can_see_class_scope = 1;
@ -2696,7 +2699,7 @@ symtable_visit_annotations(struct symtable *st, stmt_ty o, arguments_ty a, expr_
VISIT(st, expr, returns); VISIT(st, expr, returns);
} }
if (!symtable_exit_block(st)) { if (!symtable_exit_block(st)) {
VISIT_QUIT(st, 0); return 0;
} }
return 1; return 1;
} }
@ -2963,7 +2966,7 @@ symtable_raise_if_comprehension_block(struct symtable *st, expr_ty e) {
(type == DictComprehension) ? "'yield' inside dict comprehension" : (type == DictComprehension) ? "'yield' inside dict comprehension" :
"'yield' inside generator expression"); "'yield' inside generator expression");
SET_ERROR_LOCATION(st->st_filename, LOCATION(e)); SET_ERROR_LOCATION(st->st_filename, LOCATION(e));
VISIT_QUIT(st, 0); return 0;
} }
static int static int