mirror of
https://github.com/python/cpython.git
synced 2025-07-08 03:45:36 +00:00
gh-122595: Add more error checks in the compiler (GH-122596)
This commit is contained in:
parent
94a4bd79a7
commit
e74680b718
2 changed files with 145 additions and 52 deletions
|
@ -505,21 +505,35 @@ dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset)
|
|||
deterministic, then the generated bytecode is not deterministic.
|
||||
*/
|
||||
sorted_keys = PyDict_Keys(src);
|
||||
if (sorted_keys == NULL)
|
||||
if (sorted_keys == NULL) {
|
||||
Py_DECREF(dest);
|
||||
return NULL;
|
||||
}
|
||||
if (PyList_Sort(sorted_keys) != 0) {
|
||||
Py_DECREF(sorted_keys);
|
||||
Py_DECREF(dest);
|
||||
return NULL;
|
||||
}
|
||||
num_keys = PyList_GET_SIZE(sorted_keys);
|
||||
|
||||
for (key_i = 0; key_i < num_keys; key_i++) {
|
||||
/* XXX this should probably be a macro in symtable.h */
|
||||
long vi;
|
||||
k = PyList_GET_ITEM(sorted_keys, key_i);
|
||||
v = PyDict_GetItemWithError(src, k);
|
||||
assert(v && PyLong_Check(v));
|
||||
vi = PyLong_AS_LONG(v);
|
||||
if (!v) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetObject(PyExc_KeyError, k);
|
||||
}
|
||||
Py_DECREF(sorted_keys);
|
||||
Py_DECREF(dest);
|
||||
return NULL;
|
||||
}
|
||||
long vi = PyLong_AsLong(v);
|
||||
if (vi == -1 && PyErr_Occurred()) {
|
||||
Py_DECREF(sorted_keys);
|
||||
Py_DECREF(dest);
|
||||
return NULL;
|
||||
}
|
||||
/* XXX this should probably be a macro in symtable.h */
|
||||
scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
|
||||
|
||||
if (scope == scope_type || vi & flag) {
|
||||
|
@ -631,6 +645,7 @@ compiler_set_qualname(struct compiler *c)
|
|||
|
||||
scope = _PyST_GetScope(parent->u_ste, mangled);
|
||||
Py_DECREF(mangled);
|
||||
RETURN_IF_ERROR(scope);
|
||||
assert(scope != GLOBAL_IMPLICIT);
|
||||
if (scope == GLOBAL_EXPLICIT)
|
||||
force_global = 1;
|
||||
|
@ -1648,7 +1663,7 @@ dict_lookup_arg(PyObject *dict, PyObject *name)
|
|||
if (v == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
return PyLong_AS_LONG(v);
|
||||
return PyLong_AsLong(v);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1671,7 +1686,7 @@ compiler_lookup_arg(struct compiler *c, PyCodeObject *co, PyObject *name)
|
|||
else {
|
||||
arg = dict_lookup_arg(c->u->u_metadata.u_freevars, name);
|
||||
}
|
||||
if (arg == -1) {
|
||||
if (arg == -1 && !PyErr_Occurred()) {
|
||||
PyObject *freevars = _PyCode_GetFreevars(co);
|
||||
if (freevars == NULL) {
|
||||
PyErr_Clear();
|
||||
|
@ -4085,6 +4100,8 @@ compiler_nameop(struct compiler *c, location loc,
|
|||
case GLOBAL_EXPLICIT:
|
||||
optype = OP_GLOBAL;
|
||||
break;
|
||||
case -1:
|
||||
goto error;
|
||||
default:
|
||||
/* scope can be 0 */
|
||||
break;
|
||||
|
@ -4638,6 +4655,7 @@ is_import_originated(struct compiler *c, expr_ty e)
|
|||
}
|
||||
|
||||
long flags = _PyST_GetSymbol(SYMTABLE(c)->st_top, e->v.Name.id);
|
||||
RETURN_IF_ERROR(flags);
|
||||
return flags & DEF_IMPORT;
|
||||
}
|
||||
|
||||
|
@ -4657,10 +4675,12 @@ can_optimize_super_call(struct compiler *c, expr_ty attr)
|
|||
PyObject *super_name = e->v.Call.func->v.Name.id;
|
||||
// detect statically-visible shadowing of 'super' name
|
||||
int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), super_name);
|
||||
RETURN_IF_ERROR(scope);
|
||||
if (scope != GLOBAL_IMPLICIT) {
|
||||
return 0;
|
||||
}
|
||||
scope = _PyST_GetScope(SYMTABLE(c)->st_top, super_name);
|
||||
RETURN_IF_ERROR(scope);
|
||||
if (scope != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -4767,7 +4787,9 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
|
|||
}
|
||||
|
||||
/* Check that the base object is not something that is imported */
|
||||
if (is_import_originated(c, meth->v.Attribute.value)) {
|
||||
int ret = is_import_originated(c, meth->v.Attribute.value);
|
||||
RETURN_IF_ERROR(ret);
|
||||
if (ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4795,7 +4817,9 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
|
|||
/* Alright, we can optimize the code. */
|
||||
location loc = LOC(meth);
|
||||
|
||||
if (can_optimize_super_call(c, meth)) {
|
||||
ret = can_optimize_super_call(c, meth);
|
||||
RETURN_IF_ERROR(ret);
|
||||
if (ret) {
|
||||
RETURN_IF_ERROR(load_args_for_super(c, meth->v.Attribute.value));
|
||||
int opcode = asdl_seq_LEN(meth->v.Attribute.value->v.Call.args) ?
|
||||
LOAD_SUPER_METHOD : LOAD_ZERO_SUPER_METHOD;
|
||||
|
@ -5367,8 +5391,10 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
|
|||
PyObject *k, *v;
|
||||
Py_ssize_t pos = 0;
|
||||
while (PyDict_Next(entry->ste_symbols, &pos, &k, &v)) {
|
||||
assert(PyLong_Check(v));
|
||||
long symbol = PyLong_AS_LONG(v);
|
||||
long symbol = PyLong_AsLong(v);
|
||||
if (symbol == -1 && PyErr_Occurred()) {
|
||||
return ERROR;
|
||||
}
|
||||
long scope = (symbol >> SCOPE_OFFSET) & SCOPE_MASK;
|
||||
PyObject *outv = PyDict_GetItemWithError(SYMTABLE_ENTRY(c)->ste_symbols, k);
|
||||
if (outv == NULL) {
|
||||
|
@ -5377,8 +5403,11 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
|
|||
}
|
||||
outv = _PyLong_GetZero();
|
||||
}
|
||||
assert(PyLong_CheckExact(outv));
|
||||
long outsc = (PyLong_AS_LONG(outv) >> SCOPE_OFFSET) & SCOPE_MASK;
|
||||
long outsymbol = PyLong_AsLong(outv);
|
||||
if (outsymbol == -1 && PyErr_Occurred()) {
|
||||
return ERROR;
|
||||
}
|
||||
long outsc = (outsymbol >> SCOPE_OFFSET) & SCOPE_MASK;
|
||||
// If a name has different scope inside than outside the comprehension,
|
||||
// we need to temporarily handle it with the right scope while
|
||||
// compiling the comprehension. If it's free in the comprehension
|
||||
|
@ -6064,14 +6093,18 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
|
|||
return compiler_formatted_value(c, e);
|
||||
/* The following exprs can be assignment targets. */
|
||||
case Attribute_kind:
|
||||
if (e->v.Attribute.ctx == Load && can_optimize_super_call(c, e)) {
|
||||
RETURN_IF_ERROR(load_args_for_super(c, e->v.Attribute.value));
|
||||
int opcode = asdl_seq_LEN(e->v.Attribute.value->v.Call.args) ?
|
||||
LOAD_SUPER_ATTR : LOAD_ZERO_SUPER_ATTR;
|
||||
ADDOP_NAME(c, loc, opcode, e->v.Attribute.attr, names);
|
||||
loc = update_start_location_to_match_attr(c, loc, e);
|
||||
ADDOP(c, loc, NOP);
|
||||
return SUCCESS;
|
||||
if (e->v.Attribute.ctx == Load) {
|
||||
int ret = can_optimize_super_call(c, e);
|
||||
RETURN_IF_ERROR(ret);
|
||||
if (ret) {
|
||||
RETURN_IF_ERROR(load_args_for_super(c, e->v.Attribute.value));
|
||||
int opcode = asdl_seq_LEN(e->v.Attribute.value->v.Call.args) ?
|
||||
LOAD_SUPER_ATTR : LOAD_ZERO_SUPER_ATTR;
|
||||
ADDOP_NAME(c, loc, opcode, e->v.Attribute.attr, names);
|
||||
loc = update_start_location_to_match_attr(c, loc, e);
|
||||
ADDOP(c, loc, NOP);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
RETURN_IF_ERROR(compiler_maybe_add_static_attribute_to_class(c, e));
|
||||
VISIT(c, expr, e->v.Attribute.value);
|
||||
|
@ -7300,7 +7333,8 @@ consts_dict_keys_inorder(PyObject *dict)
|
|||
if (consts == NULL)
|
||||
return NULL;
|
||||
while (PyDict_Next(dict, &pos, &k, &v)) {
|
||||
i = PyLong_AS_LONG(v);
|
||||
assert(PyLong_CheckExact(v));
|
||||
i = PyLong_AsLong(v);
|
||||
/* The keys of the dictionary can be tuples wrapping a constant.
|
||||
* (see dict_add_o and _PyCode_ConstantKey). In that case
|
||||
* the object we want is always second. */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue