diff options
author | David Malcolm <dmalcolm@redhat.com> | 2020-11-30 14:32:28 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2020-11-30 14:32:28 -0500 |
commit | 66dde7bc64b75d4a338266333c9c490b12d49825 (patch) | |
tree | 5f44f4fbd3e979b9557c8d390fca30745ce042c9 /gcc/tree-vectorizer.c | |
parent | 5ddb6eca28a2b58656c5d786a4462024ab74618f (diff) | |
download | gcc-66dde7bc64b75d4a338266333c9c490b12d49825.zip gcc-66dde7bc64b75d4a338266333c9c490b12d49825.tar.gz gcc-66dde7bc64b75d4a338266333c9c490b12d49825.tar.bz2 |
Add analyzer plugin support and CPython GIL example
This patch adds a new GCC plugin event: PLUGIN_ANALYZER_INIT, called
when -fanalyzer is starting, allowing for GCC plugins to register
additional state-machine-based checks within -fanalyzer. The idea
is that 3rd-party code might want to add domain-specific checks for
its own APIs - with the caveat that the analyzer is itself still
rather experimental.
As an example, the patch adds a proof-of-concept plugin to the testsuite
for checking CPython code: verifying that code that relinquishes
CPython's global interpreter lock doesn't attempt to do anything with
PyObjects in the sections where the lock isn't held. It also adds a
warning about nested releases of the lock, which is forbidden.
For example:
demo.c: In function 'foo':
demo.c:11:3: warning: use of PyObject '*(obj)' without the GIL
11 | Py_INCREF (obj);
| ^~~~~~~~~
'test': events 1-3
|
| 15 | void test (PyObject *obj)
| | ^~~~
| | |
| | (1) entry to 'test'
| 16 | {
| 17 | Py_BEGIN_ALLOW_THREADS
| | ~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (2) releasing the GIL here
| 18 | foo (obj);
| | ~~~~~~~~~
| | |
| | (3) calling 'foo' from 'test'
|
+--> 'foo': events 4-5
|
| 9 | foo (PyObject *obj)
| | ^~~
| | |
| | (4) entry to 'foo'
| 10 | {
| 11 | Py_INCREF (obj);
| | ~~~~~~~~~
| | |
| | (5) PyObject '*(obj)' used here without the GIL
|
Doing so requires adding some logic for ignoring macro expansions in
analyzer diagnostics, since the insides of Py_INCREF and
Py_BEGIN_ALLOW_THREADS are not of interest to the user for these cases.
gcc/analyzer/ChangeLog:
* analyzer-pass.cc (pass_analyzer::execute): Move sorry call to...
(sorry_no_analyzer): New.
* analyzer.h (class state_machine): New forward decl.
(class logger): New forward decl.
(class plugin_analyzer_init_iface): New.
(sorry_no_analyzer): New decl.
* checker-path.cc (checker_path::fixup_locations): New.
* checker-path.h (checker_event::set_location): New.
(checker_path::fixup_locations): New decl.
* diagnostic-manager.cc
(diagnostic_manager::emit_saved_diagnostic): Call
checker_path::fixup_locations, and call fixup_location
on the primary location.
* engine.cc: Include "plugin.h".
(class plugin_analyzer_init_impl): New.
(impl_run_checkers): Invoke PLUGIN_ANALYZER_INIT callbacks.
* pending-diagnostic.h (pending_diagnostic::fixup_location): New
vfunc.
gcc/ChangeLog:
* doc/plugins.texi (Plugin callbacks): Add PLUGIN_ANALYZER_INIT.
* plugin.c (register_callback): Likewise.
(invoke_plugin_callbacks_full): Likewise.
* plugin.def (PLUGIN_ANALYZER_INIT): New event.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/analyzer_gil_plugin.c: New test.
* gcc.dg/plugin/gil-1.c: New test.
* gcc.dg/plugin/gil.h: New header.
* gcc.dg/plugin/plugin.exp (plugin_test_list): Add the new plugin
and test.
Diffstat (limited to 'gcc/tree-vectorizer.c')
0 files changed, 0 insertions, 0 deletions