[Python-checkins] [2.7] bpo-33132: Fix reference counting issues in the compiler. (GH-6209). (GH-6322)

Serhiy Storchaka webhook-mailer at python.org
Sun Apr 1 03:26:36 EDT 2018


https://github.com/python/cpython/commit/72f3e0887500e00867fa16ce5aaab12fae853b63
commit: 72f3e0887500e00867fa16ce5aaab12fae853b63
branch: 2.7
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2018-04-01T10:26:33+03:00
summary:

[2.7] bpo-33132: Fix reference counting issues in the compiler. (GH-6209). (GH-6322)

(cherry picked from commit a95d98607efe0c43475b354543e49bf8e240bc6f)

Co-authored-by: Serhiy Storchaka <storchaka at gmail.com>

files:
M Python/compile.c

diff --git a/Python/compile.c b/Python/compile.c
index 9c9b23698520..4fe69e12bf84 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1075,6 +1075,15 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
         return 0; \
 }
 
+/* Same as ADDOP_O, but steals a reference. */
+#define ADDOP_N(C, OP, O, TYPE) { \
+    if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \
+        Py_DECREF((O)); \
+        return 0; \
+    } \
+    Py_DECREF((O)); \
+}
+
 #define ADDOP_NAME(C, OP, O, TYPE) { \
     if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \
         return 0; \
@@ -1890,8 +1899,7 @@ compiler_import_as(struct compiler *c, identifier name, identifier asname)
                                 dot ? dot - src : strlen(src));
             if (!attr)
                 return 0;
-            ADDOP_O(c, LOAD_ATTR, attr, names);
-            Py_DECREF(attr);
+            ADDOP_N(c, LOAD_ATTR, attr, names);
             src = dot + 1;
         }
     }
@@ -1923,8 +1931,7 @@ compiler_import(struct compiler *c, stmt_ty s)
         if (level == NULL)
             return 0;
 
-        ADDOP_O(c, LOAD_CONST, level, consts);
-        Py_DECREF(level);
+        ADDOP_N(c, LOAD_CONST, level, consts);
         ADDOP_O(c, LOAD_CONST, Py_None, consts);
         ADDOP_NAME(c, IMPORT_NAME, alias->name, names);
 
@@ -1959,8 +1966,7 @@ compiler_from_import(struct compiler *c, stmt_ty s)
 {
     int i, n = asdl_seq_LEN(s->v.ImportFrom.names);
 
-    PyObject *names = PyTuple_New(n);
-    PyObject *level;
+    PyObject *level, *names;
     static PyObject *empty_string;
 
     if (!empty_string) {
@@ -1969,9 +1975,6 @@ compiler_from_import(struct compiler *c, stmt_ty s)
             return 0;
     }
 
-    if (!names)
-        return 0;
-
     if (s->v.ImportFrom.level == 0 && c->c_flags &&
         !(c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT))
         level = PyInt_FromLong(-1);
@@ -1979,9 +1982,13 @@ compiler_from_import(struct compiler *c, stmt_ty s)
         level = PyInt_FromLong(s->v.ImportFrom.level);
 
     if (!level) {
-        Py_DECREF(names);
         return 0;
     }
+    ADDOP_N(c, LOAD_CONST, level, consts);
+
+    names = PyTuple_New(n);
+    if (!names)
+        return 0;
 
     /* build up the names */
     for (i = 0; i < n; i++) {
@@ -1992,16 +1999,12 @@ compiler_from_import(struct compiler *c, stmt_ty s)
 
     if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module &&
         !strcmp(PyString_AS_STRING(s->v.ImportFrom.module), "__future__")) {
-        Py_DECREF(level);
         Py_DECREF(names);
         return compiler_error(c, "from __future__ imports must occur "
                               "at the beginning of the file");
     }
+    ADDOP_N(c, LOAD_CONST, names, consts);
 
-    ADDOP_O(c, LOAD_CONST, level, consts);
-    Py_DECREF(level);
-    ADDOP_O(c, LOAD_CONST, names, consts);
-    Py_DECREF(names);
     if (s->v.ImportFrom.module) {
         ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names);
     }
@@ -2024,7 +2027,6 @@ compiler_from_import(struct compiler *c, stmt_ty s)
             store_name = alias->asname;
 
         if (!compiler_nameop(c, store_name, Store)) {
-            Py_DECREF(names);
             return 0;
         }
     }
@@ -2391,8 +2393,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
                             "param invalid for local variable");
             return 0;
         }
-        ADDOP_O(c, op, mangled, varnames);
-        Py_DECREF(mangled);
+        ADDOP_N(c, op, mangled, varnames);
         return 1;
     case OP_GLOBAL:
         switch (ctx) {



More information about the Python-checkins mailing list