]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #9566: compile.c uses Py_ssize_t instead of int to store sizes to fix
authorVictor Stinner <victor.stinner@gmail.com>
Tue, 19 Nov 2013 21:23:20 +0000 (22:23 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Tue, 19 Nov 2013 21:23:20 +0000 (22:23 +0100)
compiler warnings on Windows 64-bit. Use Py_SAFE_DOWNCAST() where the final
downcast is needed.

The bytecode doesn't support integer parameters larger than 32-bit yet.

Python/compile.c

index 8b00211c9fd07346438395418d4660d69a7e9a20..dde6dcff4bdcd99f3ee912ca3251e82584c0ba52 100644 (file)
@@ -170,7 +170,7 @@ static basicblock *compiler_new_block(struct compiler *);
 static int compiler_next_instr(struct compiler *, basicblock *);
 static int compiler_addop(struct compiler *, int);
 static int compiler_addop_o(struct compiler *, int, PyObject *, PyObject *);
-static int compiler_addop_i(struct compiler *, int, int);
+static int compiler_addop_i(struct compiler *, Py_ssize_t, Py_ssize_t);
 static int compiler_addop_j(struct compiler *, int, basicblock *, int);
 static basicblock *compiler_use_new_block(struct compiler *);
 static int compiler_error(struct compiler *, const char *);
@@ -195,7 +195,7 @@ static int inplace_binop(struct compiler *, operator_ty);
 static int expr_constant(struct compiler *, expr_ty);
 
 static int compiler_with(struct compiler *, stmt_ty, int);
-static int compiler_call_helper(struct compiler *c, int n,
+static int compiler_call_helper(struct compiler *c, Py_ssize_t n,
                                 asdl_seq *args,
                                 asdl_seq *keywords,
                                 expr_ty starargs,
@@ -388,7 +388,7 @@ list2dict(PyObject *list)
 
     n = PyList_Size(list);
     for (i = 0; i < n; i++) {
-        v = PyLong_FromLong(i);
+        v = PyLong_FromSsize_t(i);
         if (!v) {
             Py_DECREF(dict);
             return NULL;
@@ -416,7 +416,7 @@ each key.
 */
 
 static PyObject *
-dictbytype(PyObject *src, int scope_type, int flag, int offset)
+dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset)
 {
     Py_ssize_t i = offset, scope, num_keys, key_i;
     PyObject *k, *v, *dest = PyDict_New();
@@ -450,7 +450,7 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
         scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
 
         if (scope == scope_type || vi & flag) {
-            PyObject *tuple, *item = PyLong_FromLong(i);
+            PyObject *tuple, *item = PyLong_FromSsize_t(i);
             if (item == NULL) {
                 Py_DECREF(sorted_keys);
                 Py_DECREF(dest);
@@ -635,7 +635,7 @@ compiler_enter_scope(struct compiler *c, identifier name,
 static void
 compiler_exit_scope(struct compiler *c)
 {
-    int n;
+    Py_ssize_t n;
     PyObject *capsule;
 
     c->c_nestlevel--;
@@ -1128,7 +1128,7 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
         if (PyErr_Occurred())
             return -1;
         arg = PyDict_Size(dict);
-        v = PyLong_FromLong(arg);
+        v = PyLong_FromSsize_t(arg);
         if (!v) {
             Py_DECREF(t);
             return -1;
@@ -1150,7 +1150,7 @@ static int
 compiler_addop_o(struct compiler *c, int opcode, PyObject *dict,
                      PyObject *o)
 {
-    int arg = compiler_add_o(c, dict, o);
+    Py_ssize_t arg = compiler_add_o(c, dict, o);
     if (arg < 0)
         return 0;
     return compiler_addop_i(c, opcode, arg);
@@ -1160,7 +1160,7 @@ static int
 compiler_addop_name(struct compiler *c, int opcode, PyObject *dict,
                     PyObject *o)
 {
-    int arg;
+    Py_ssize_t arg;
     PyObject *mangled = _Py_Mangle(c->u->u_private, o);
     if (!mangled)
         return 0;
@@ -1176,15 +1176,21 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict,
 */
 
 static int
-compiler_addop_i(struct compiler *c, int opcode, int oparg)
+compiler_addop_i(struct compiler *c, Py_ssize_t opcode, Py_ssize_t oparg)
 {
     struct instr *i;
     int off;
+
+    /* Integer arguments are limit to 16-bit. There is an extension for 32-bit
+       integer arguments. */
+    assert(INT32_MIN <= opcode);
+    assert(opcode <= INT32_MAX);
+
     off = compiler_next_instr(c, c->u->u_curblock);
     if (off < 0)
         return 0;
     i = &c->u->u_curblock->b_instr[off];
-    i->i_opcode = opcode;
+    i->i_opcode = Py_SAFE_DOWNCAST(opcode, Py_ssize_t, int);
     i->i_oparg = oparg;
     i->i_hasarg = 1;
     compiler_set_lineno(c, off);
@@ -1436,9 +1442,9 @@ compiler_lookup_arg(PyObject *dict, PyObject *name)
 }
 
 static int
-compiler_make_closure(struct compiler *c, PyCodeObject *co, int args, PyObject *qualname)
+compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t args, PyObject *qualname)
 {
-    int i, free = PyCode_GetNumFree(co);
+    Py_ssize_t i, free = PyCode_GetNumFree(co);
     if (qualname == NULL)
         qualname = co->co_name;
 
@@ -1565,7 +1571,7 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,
        */
     static identifier return_str;
     PyObject *names;
-    int len;
+    Py_ssize_t len;
     names = PyList_New(0);
     if (!names)
         return -1;
@@ -1602,7 +1608,7 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,
     if (len) {
         /* convert names to a tuple and place on stack */
         PyObject *elt;
-        int i;
+        Py_ssize_t i;
         PyObject *s = PyTuple_New(len);
         if (!s)
             goto error;
@@ -1616,7 +1622,9 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,
         len++; /* include the just-pushed tuple */
     }
     Py_DECREF(names);
-    return len;
+
+    /* We just checked that len <= 65535, see above */
+    return Py_SAFE_DOWNCAST(len, Py_ssize_t, int);
 
 error:
     Py_DECREF(names);
@@ -1632,7 +1640,8 @@ compiler_function(struct compiler *c, stmt_ty s)
     expr_ty returns = s->v.FunctionDef.returns;
     asdl_seq* decos = s->v.FunctionDef.decorator_list;
     stmt_ty st;
-    int i, n, docstring, kw_default_count = 0, arglength;
+    Py_ssize_t i, n, arglength;
+    int docstring, kw_default_count = 0;
     int num_annotations;
 
     assert(s->kind == FunctionDef_kind);
@@ -1851,7 +1860,8 @@ compiler_lambda(struct compiler *c, expr_ty e)
     PyCodeObject *co;
     PyObject *qualname;
     static identifier name;
-    int kw_default_count = 0, arglength;
+    int kw_default_count = 0;
+    Py_ssize_t arglength;
     arguments_ty args = e->v.Lambda.args;
     assert(e->kind == Lambda_kind);
 
@@ -2162,7 +2172,7 @@ static int
 compiler_try_except(struct compiler *c, stmt_ty s)
 {
     basicblock *body, *orelse, *except, *end;
-    int i, n;
+    Py_ssize_t i, n;
 
     body = compiler_new_block(c);
     except = compiler_new_block(c);
@@ -2328,7 +2338,7 @@ compiler_import(struct compiler *c, stmt_ty s)
        module names.
        XXX Perhaps change the representation to make this case simpler?
      */
-    int i, n = asdl_seq_LEN(s->v.Import.names);
+    Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names);
 
     for (i = 0; i < n; i++) {
         alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
@@ -2372,7 +2382,7 @@ compiler_import(struct compiler *c, stmt_ty s)
 static int
 compiler_from_import(struct compiler *c, stmt_ty s)
 {
-    int i, n = asdl_seq_LEN(s->v.ImportFrom.names);
+    Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names);
 
     PyObject *names = PyTuple_New(n);
     PyObject *level;
@@ -2489,7 +2499,7 @@ compiler_assert(struct compiler *c, stmt_ty s)
 static int
 compiler_visit_stmt(struct compiler *c, stmt_ty s)
 {
-    int i, n;
+    Py_ssize_t i, n;
 
     /* Always assign a lineno to the next instruction for a stmt. */
     c->u->u_lineno = s->lineno;
@@ -2537,12 +2547,12 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
         if (s->v.Raise.exc) {
             VISIT(c, expr, s->v.Raise.exc);
             n++;
-        if (s->v.Raise.cause) {
-        VISIT(c, expr, s->v.Raise.cause);
-        n++;
-        }
+            if (s->v.Raise.cause) {
+                VISIT(c, expr, s->v.Raise.cause);
+                n++;
+            }
         }
-        ADDOP_I(c, RAISE_VARARGS, n);
+        ADDOP_I(c, RAISE_VARARGS, (int)n);
         break;
     case Try_kind:
         return compiler_try(c, s);
@@ -2702,7 +2712,8 @@ inplace_binop(struct compiler *c, operator_ty op)
 static int
 compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
 {
-    int op, scope, arg;
+    int op, scope;
+    Py_ssize_t arg;
     enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype;
 
     PyObject *dict = c->u->u_names;
@@ -2828,7 +2839,8 @@ static int
 compiler_boolop(struct compiler *c, expr_ty e)
 {
     basicblock *end;
-    int jumpi, i, n;
+    int jumpi;
+    Py_ssize_t i, n;
     asdl_seq *s;
 
     assert(e->kind == BoolOp_kind);
@@ -2854,7 +2866,7 @@ compiler_boolop(struct compiler *c, expr_ty e)
 static int
 compiler_list(struct compiler *c, expr_ty e)
 {
-    int n = asdl_seq_LEN(e->v.List.elts);
+    Py_ssize_t n = asdl_seq_LEN(e->v.List.elts);
     if (e->v.List.ctx == Store) {
         int i, seen_star = 0;
         for (i = 0; i < n; i++) {
@@ -2887,7 +2899,7 @@ compiler_list(struct compiler *c, expr_ty e)
 static int
 compiler_tuple(struct compiler *c, expr_ty e)
 {
-    int n = asdl_seq_LEN(e->v.Tuple.elts);
+    Py_ssize_t n = asdl_seq_LEN(e->v.Tuple.elts);
     if (e->v.Tuple.ctx == Store) {
         int i, seen_star = 0;
         for (i = 0; i < n; i++) {
@@ -2920,7 +2932,7 @@ compiler_tuple(struct compiler *c, expr_ty e)
 static int
 compiler_compare(struct compiler *c, expr_ty e)
 {
-    int i, n;
+    Py_ssize_t i, n;
     basicblock *cleanup = NULL;
 
     /* XXX the logic can be cleaned up for 1 or multiple comparisons */
@@ -2976,11 +2988,11 @@ compiler_call(struct compiler *c, expr_ty e)
 /* shared code between compiler_call and compiler_class */
 static int
 compiler_call_helper(struct compiler *c,
-                     int n, /* Args already pushed */
-             asdl_seq *args,
-             asdl_seq *keywords,
-             expr_ty starargs,
-             expr_ty kwargs)
+                     Py_ssize_t n, /* Args already pushed */
+                     asdl_seq *args,
+                     asdl_seq *keywords,
+                     expr_ty starargs,
+                     expr_ty kwargs)
 {
     int code = 0;
 
@@ -3041,7 +3053,7 @@ compiler_comprehension_generator(struct compiler *c,
 
     comprehension_ty gen;
     basicblock *start, *anchor, *skip, *if_cleanup;
-    int i, n;
+    Py_ssize_t i, n;
 
     start = compiler_new_block(c);
     skip = compiler_new_block(c);
@@ -3380,7 +3392,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos)
 static int
 compiler_visit_expr(struct compiler *c, expr_ty e)
 {
-    int i, n;
+    Py_ssize_t i, n;
 
     /* If expr e has a different line number than the last expr/stmt,
        set a new line number for the next instruction.
@@ -3409,6 +3421,8 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
         return compiler_ifexp(c, e);
     case Dict_kind:
         n = asdl_seq_LEN(e->v.Dict.values);
+        /* BUILD_MAP parameter is only used to preallocate the dictionary,
+           it doesn't need to be exact */
         ADDOP_I(c, BUILD_MAP, (n>0xFFFF ? 0xFFFF : n));
         for (i = 0; i < n; i++) {
             VISIT(c, expr,
@@ -3756,7 +3770,7 @@ compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
     case ExtSlice_kind:
         kindname = "extended slice";
         if (ctx != AugStore) {
-            int i, n = asdl_seq_LEN(s->v.ExtSlice.dims);
+            Py_ssize_t i, n = asdl_seq_LEN(s->v.ExtSlice.dims);
             for (i = 0; i < n; i++) {
                 slice_ty sub = (slice_ty)asdl_seq_GET(
                     s->v.ExtSlice.dims, i);
@@ -3934,7 +3948,7 @@ static int
 assemble_lnotab(struct assembler *a, struct instr *i)
 {
     int d_bytecode, d_lineno;
-    int len;
+    Py_ssize_t len;
     unsigned char *lnotab;
 
     d_bytecode = a->a_offset - a->a_lineno_off;
@@ -4125,7 +4139,7 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c)
 }
 
 static PyObject *
-dict_keys_inorder(PyObject *dict, int offset)
+dict_keys_inorder(PyObject *dict, Py_ssize_t offset)
 {
     PyObject *tuple, *k, *v;
     Py_ssize_t i, pos = 0, size = PyDict_Size(dict);
@@ -4150,7 +4164,8 @@ static int
 compute_code_flags(struct compiler *c)
 {
     PySTEntryObject *ste = c->u->u_ste;
-    int flags = 0, n;
+    int flags = 0;
+    Py_ssize_t n;
     if (ste->ste_type == FunctionBlock) {
         flags |= CO_NEWLOCALS;
         if (!ste->ste_unoptimized)
@@ -4174,9 +4189,9 @@ compute_code_flags(struct compiler *c)
     if (n == 0) {
         n = PyDict_Size(c->u->u_cellvars);
         if (n < 0)
-        return -1;
+            return -1;
         if (n == 0) {
-        flags |= CO_NOFREE;
+            flags |= CO_NOFREE;
         }
     }
 
@@ -4195,7 +4210,9 @@ makecode(struct compiler *c, struct assembler *a)
     PyObject *freevars = NULL;
     PyObject *cellvars = NULL;
     PyObject *bytecode = NULL;
-    int nlocals, flags;
+    Py_ssize_t nlocals;
+    int nlocals_int;
+    int flags;
 
     tmp = dict_keys_inorder(c->u->u_consts, 0);
     if (!tmp)
@@ -4214,7 +4231,11 @@ makecode(struct compiler *c, struct assembler *a)
     freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars));
     if (!freevars)
         goto error;
+
     nlocals = PyDict_Size(c->u->u_varnames);
+    assert(nlocals < INT_MAX);
+    nlocals_int = Py_SAFE_DOWNCAST(nlocals, Py_ssize_t, int);
+
     flags = compute_code_flags(c);
     if (flags < 0)
         goto error;
@@ -4230,7 +4251,7 @@ makecode(struct compiler *c, struct assembler *a)
     consts = tmp;
 
     co = PyCode_New(c->u->u_argcount, c->u->u_kwonlyargcount,
-                    nlocals, stackdepth(c), flags,
+                    nlocals_int, stackdepth(c), flags,
                     bytecode, consts, names, varnames,
                     freevars, cellvars,
                     c->c_filename, c->u->u_name,
@@ -4349,4 +4370,3 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
     return PyAST_CompileEx(mod, filename, flags, -1, arena);
 }
 
-