mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
c2c64cfcd07b1060a6c16d1695972938ea643c1f
In GCC 14 the testsuite gained a plugin that "teaches" the analyzer about the CPython API, trying for find common mistakes: https://gcc.gnu.org/wiki/StaticAnalyzer/CPython Unfortunately, this has been crashing for more recent versions of CPython. Specifically, in Python 3.11, PyObject's ob_refcnt was moved to an anonymous union (as part of PEP 683 "Immortal Objects, Using a Fixed Refcount"). The plugin attempts to find the field but fails, but has no error-handling, leading to a null pointer dereference. Also, https://github.com/python/cpython/pull/101292 moved the "ob_digit" from struct _longobject to a new field long_value of a new struct _PyLongValue, leading to similar analyzer crashes when not finding the field. The following patch fixes this by * looking within the anonymous union for the ob_refcnt field if it can't find it directly * gracefully handling the case of not finding "ob_digit" in PyLongObject * doing more lookups once at plugin startup, rather than continuously on analyzing API calls * adding diagnostics and more error-handling to the plugin startup, so that if it can't find something in the Python headers it emits a useful note when disabling itself, e.g. cc1: note: could not find field 'ob_digit' of CPython type 'PyLongObject' {aka 'struct _longobject'} * replacing some copy-and-pasted code with member functions of a new "class api" (though various other cleanups could be done) Tested with: * CPython 3.8: all tests continue to PASS * CPython 3.13: fixes the ICEs, 2 FAILs remain (reference counting false negatives) Given that this is already a large patch, I'm opting to only fix the crashes and defer the 2 remainings FAILs and other cleanups to followup work. gcc/analyzer/ChangeLog: PR testsuite/112520 * region-model-manager.cc (region_model_manager::get_field_region): Assert that the args are non-null. gcc/testsuite/ChangeLog: PR analyzer/107646 PR testsuite/112520 * gcc.dg/plugin/analyzer_cpython_plugin.cc: Move everything from namespace ana:: into ana::cpython_plugin. Move global tree values into a new "class api". (pyobj_record): Replace with api.m_type_PyObject. (pyobj_ptr_tree): Replace with api.m_type_PyObject_ptr. (pyobj_ptr_ptr): Replace with api.m_type_PyObject_ptr_ptr. (varobj_record): Replace with api.m_type_PyVarObject. (pylistobj_record): Replace with api.m_type_PyListObject. (pylongobj_record): Replace with api.m_type_PyLongObject. (pylongtype_vardecl): Replace with api.m_vardecl_PyLong_Type. (pylisttype_vardecl): Replace with api.m_vardecl_PyList_Type. (get_field_by_name): Add "complain" param and use it to issue a note on failure. Assert that type and name are non-null. Don't crash on fields that are anonymous unions, and special-case looking within them for "ob_refcnt" to work around the Python 3.11 change for PEP 683 (immortal objects). (get_sizeof_pyobjptr): Convert to... (api::get_sval_sizeof_PyObject_ptr): ...this (init_ob_refcnt_field): Convert to... (api::init_ob_refcnt_field): ...this. (set_ob_type_field): Convert to... (api::set_ob_type_field): ..this. (api::init_PyObject_HEAD): New. (api::get_region_PyObject_ob_refcnt): New. (api::do_Py_INCREF): New. (api::get_region_PyVarObject_ob_size): New. (api::get_region_PyLongObject_ob_digit): New. (inc_field_val): Convert to... (api::inc_field_val): ...this. (refcnt_mismatch::refcnt_mismatch): Add tree params for refcounts and initialize corresponding fields. Fix whitespace. (refcnt_mismatch::emit): Use stored tree values, rather than assuming we have constants, and crashing non-constants. Delete commented-out dead code. (refcnt_mismatch::foo): Delete. (refcnt_mismatch::m_expected_refcnt_tree): New field. (refcnt_mismatch::m_actual_refcnt_tree): New field. (retrieve_ob_refcnt_sval): Simplify using class api. (count_pyobj_references): Likewise. (check_refcnt): Likewise. Don't warn on UNKNOWN values. Use get_representative_tree for the expected and actual values and skip the warning if it fails, rather than assuming we have constants and crashing on non-constants. (count_all_references): Update comment. (kf_PyList_Append::impl_call_pre): Simplify using class api. (kf_PyList_Append::impl_call_post): Likewise. (kf_PyList_New::impl_call_post): Likewise. (kf_PyLong_FromLong::impl_call_post): Likewise. (get_stashed_type_by_name): Emit note if the type couldn't be found. (get_stashed_global_var_by_name): Likewise for globals. (init_py_structs): Convert to... (api::init_from_stashed_types): ...this. Bail out with an error code if anything fails. Look up more things at startup, rather than during analysis of calls. (ana::cpython_analyzer_events_subscriber): Rename to... (ana::cpython_plugin::analyzer_events_subscriber): ...this. (analyzer_events_subscriber::analyzer_events_subscriber): Initialize m_init_failed. (analyzer_events_subscriber::on_message<on_tu_finished>): Update for conversion of init_py_structs to api::init_from_stashed_types and bail if it fails. (analyzer_events_subscriber::on_message<on_frame_popped): Don't run if plugin initialization failed. (analyzer_events_subscriber::m_init_failed): New field. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
…
…
…
…
…
…
…
…
…
…
…
…
…
This directory contains the GNU Compiler Collection (GCC). The GNU Compiler Collection is free software. See the files whose names start with COPYING for copying permission. The manuals, and some of the runtime libraries, are under different terms; see the individual source files for details. The directory INSTALL contains copies of the installation information as HTML and plain text. The source of this information is gcc/doc/install.texi. The installation information includes details of what is included in the GCC sources and what files GCC installs. See the file gcc/doc/gcc.texi (together with other files that it includes) for usage and porting information. An online readable version of the manual is in the files gcc/doc/gcc.info*. See http://gcc.gnu.org/bugs/ for how to report bugs usefully. Copyright years on GCC source files may be listed using range notation, e.g., 1987-2012, indicating that every year in the range, inclusive, is a copyrightable year that could otherwise be listed individually.
Description
Languages
C++
30.7%
C
30.2%
Ada
14.4%
D
6.1%
Go
5.7%
Other
12.4%