Skip to content

Fix MSVC warning in frameobject.c #20590

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

Merged
merged 1 commit into from
Jun 4, 2020
Merged

Conversation

ammaraskar
Copy link
Member

This should be a safe downcast as exceeding a size of 2^30 opcodes in a single code object is extremely unlikely and there's already some hard dependencies relying on 32-bit ints like struct _frame's f_lasti, f_iblock. See PEP 611 for proposals to solidify this limit and other research on existing limits.

While it would be possible to swap this out for a Py_ssize_t, it would be a much more involved refactoring as line numbers are still reliant on being ints.

@vstinner
Copy link
Member

vstinner commented Jun 4, 2020

This fix doesn't work, I get a warning using GCC 10 on Fedora 32:

gcc -pthread -c -Wno-unused-result -Wsign-compare -g -Og -Wall -O0   -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden  -I./Include/internal  -I. -I./Include    -DPy_BUILD_CORE -o Objects/frameobject.o Objects/frameobject.c
In file included from ./Include/Python.h:61,
                 from Objects/frameobject.c:3:
Objects/frameobject.c: In function 'frame_setlineno':
./Include/pyport.h:313:35: warning: comparison of integer expressions of different signedness: 'long int' and 'long unsigned int' [-Wsign-compare]
  313 |     (assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE))
      |                                   ^~
Objects/frameobject.c:400:15: note: in expansion of macro 'Py_SAFE_DOWNCAST'
  400 |     int len = Py_SAFE_DOWNCAST(
      |               ^~~~~~~~~~~~~~~~

2^30 opcodes in a single code object is extremely unlikely

I'm not comfortable with relying on such assumption that things "should not happen in practice". I would prefer to implement a concrete runtime check in PyCode_NewWithPosOnlyArgs() to reject co_code if (size_t)PyBytes_GET_SIZE(f->f_code->co_code)/sizeof(_Py_CODEUNIT) > (size_t)INT_MAX is true. With that, you can replace Py_SAFE_DOWNCAST with (int) cast with a comment referring to PyCode_NewWithPosOnlyArgs() check.

@shihai1991
Copy link
Member

Hm, I got this warning too when I use gcc9.3 on Red Hat 4.8.5-36.

@ammaraskar
Copy link
Member Author

Aah sorry about that. I was trying to go with a narrow fix and didn't want to touch too many files. It looks like there is an assertion here https://github.com/python/cpython/blob/master/Python/ceval.c#L1328
but I agree with vstinner that this should probably just be a runtime check in codeobject. Let me open up a PR with that.

@vstinner
Copy link
Member

vstinner commented Jun 4, 2020

No problem :-) Follow-up PR: PR #20628.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants