-
-
Notifications
You must be signed in to change notification settings - Fork 34.3k
gh-143050: add helper _PyLong_InitTag() #147956
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
d7073e5
095a186
ddd329f
f6ab450
f5df517
21c59bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -185,11 +185,9 @@ long_alloc(Py_ssize_t size) | |
| return NULL; | ||
| } | ||
| _PyObject_Init((PyObject*)result, &PyLong_Type); | ||
| _PyLong_InitTag(result); | ||
| } | ||
| _PyLong_SetSignAndDigitCount(result, size != 0, size); | ||
| /* The digit has to be initialized explicitly to avoid | ||
| * use-of-uninitialized-value. */ | ||
| result->long_value.ob_digit[0] = 0; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While I'm not convinced that this initialization is useful, the comment says that it is. We should keep it, no?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggested to keep this initialization. You marked my comment as resolved, I don't understand. Do you consider that it's not needed? An alternative would be to fill digits with a pattern to detect usage of non-initialized memory when Python is built in debug mode: #ifdef Py_DEBUG
// Fill digits with a known pattern to detect usage of uninitialized memory
memset(result->long_value.ob_digit, 0xff,
sizeof(result->long_value.ob_digit[0]) * ndigits);
#endifWe use this strategy for:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you suggest to keep this just here? BTW, tests pass - I rerun one job again. |
||
| return result; | ||
| } | ||
|
|
||
|
|
@@ -258,6 +256,7 @@ _PyLong_FromMedium(sdigit x) | |
| return NULL; | ||
| } | ||
| _PyObject_Init((PyObject*)v, &PyLong_Type); | ||
| _PyLong_InitTag(v); | ||
| } | ||
| digit abs_x = x < 0 ? -x : x; | ||
| _PyLong_SetSignAndDigitCount(v, x<0?-1:1, 1); | ||
|
|
@@ -337,6 +336,7 @@ medium_from_stwodigits(stwodigits x) | |
| return PyStackRef_NULL; | ||
| } | ||
| _PyObject_Init((PyObject*)v, &PyLong_Type); | ||
| _PyLong_InitTag(v); | ||
| } | ||
| digit abs_x = x < 0 ? (digit)(-x) : (digit)x; | ||
| _PyLong_SetSignAndDigitCount(v, x<0?-1:1, 1); | ||
|
|
@@ -6011,29 +6011,34 @@ static PyObject * | |
| long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase) | ||
| { | ||
| PyLongObject *tmp, *newobj; | ||
| Py_ssize_t i, n; | ||
| Py_ssize_t size, ndigits; | ||
| int sign; | ||
|
|
||
| assert(PyType_IsSubtype(type, &PyLong_Type)); | ||
| tmp = (PyLongObject *)long_new_impl(&PyLong_Type, x, obase); | ||
| if (tmp == NULL) | ||
| return NULL; | ||
| assert(PyLong_Check(tmp)); | ||
| n = _PyLong_DigitCount(tmp); | ||
| size = _PyLong_DigitCount(tmp); | ||
| /* Fast operations for single digit integers (including zero) | ||
| * assume that there is always at least one digit present. */ | ||
| if (n == 0) { | ||
| n = 1; | ||
| } | ||
| newobj = (PyLongObject *)type->tp_alloc(type, n); | ||
| ndigits = size ? size : 1; | ||
| newobj = (PyLongObject *)type->tp_alloc(type, ndigits); | ||
| if (newobj == NULL) { | ||
| Py_DECREF(tmp); | ||
| return NULL; | ||
| } | ||
| assert(PyLong_Check(newobj)); | ||
| newobj->long_value.lv_tag = tmp->long_value.lv_tag & ~IMMORTALITY_BIT_MASK; | ||
| for (i = 0; i < n; i++) { | ||
| newobj->long_value.ob_digit[i] = tmp->long_value.ob_digit[i]; | ||
| if (_PyLong_IsCompact(tmp)) { | ||
| sign = _PyLong_CompactSign(tmp); | ||
| } | ||
| else { | ||
| sign = _PyLong_NonCompactSign(tmp); | ||
| } | ||
| _PyLong_InitTag(newobj); | ||
| _PyLong_SetSignAndDigitCount(newobj, sign, size); | ||
| memcpy(newobj->long_value.ob_digit, tmp->long_value.ob_digit, | ||
| ndigits * sizeof(digit)); | ||
| Py_DECREF(tmp); | ||
| return (PyObject *)newobj; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function doesn't initialize the first digit, so I'm not sure why you reintroduce the "The digit has to be initialized explicitly" comment: