Skip to content
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

gh-90110: Update the c-analyzer Tool #96255

Merged
merged 12 commits into from
Aug 25, 2022
1 change: 1 addition & 0 deletions Tools/c-analyzer/c_parser/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@ def _from_row(cls, row):
if kind is not cls.kind:
raise TypeError(f'expected kind {cls.kind.value!r}, got {row!r}')
fileinfo = FileInfo.from_raw(filename)
extra = None
if isinstance(data, str):
data, extra = cls._parse_data(data, fmt='row')
if extra:
Expand Down
72 changes: 72 additions & 0 deletions Tools/c-analyzer/cpython/_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,46 @@
# {ID => reason}
}

# XXX We should be handling these through known.tsv.
_OTHER_SUPPORTED_TYPES = {
# Holds tuple of strings, which we statically initialize:
'_PyArg_Parser',
# Uses of these should be const, but we don't worry about it.
'PyModuleDef',
'PyModuleDef_Slot[]',
'PyType_Spec',
'PyType_Slot[]',
'PyMethodDef',
'PyMethodDef[]',
'PyMemberDef[]',
'PyGetSetDef[]',
'PyNumberMethods',
'PySequenceMethods',
'PyMappingMethods',
'PyAsyncMethods',
'PyBufferProcs',
'PyStructSequence_Field[]',
'PyStructSequence_Desc',
}

# XXX We should normalize all cases to a single name,
# e.g. "kwlist" (currently the most common).
_KWLIST_VARIANTS = [
('*', 'kwlist'),
('*', 'keywords'),
('*', 'kwargs'),
('Modules/_csv.c', 'dialect_kws'),
('Modules/_datetimemodule.c', 'date_kws'),
('Modules/_datetimemodule.c', 'datetime_kws'),
('Modules/_datetimemodule.c', 'time_kws'),
('Modules/_datetimemodule.c', 'timezone_kws'),
('Modules/_lzmamodule.c', 'optnames'),
('Modules/_lzmamodule.c', 'arg_names'),
('Modules/cjkcodecs/multibytecodec.c', 'incnewkwarglist'),
('Modules/cjkcodecs/multibytecodec.c', 'streamkwarglist'),
('Modules/socketmodule.c', 'kwnames'),
]

KINDS = frozenset((*KIND.TYPES, KIND.VARIABLE))


Expand Down Expand Up @@ -202,6 +242,8 @@ def _check_typedep(decl, typedecl, types, knowntypes):
# XXX Fail?
return 'typespec (missing)'
elif typedecl is _info.UNKNOWN:
if _has_other_supported_type(decl):
return None
# XXX Is this right?
return 'typespec (unknown)'
elif not isinstance(typedecl, TypeDeclaration):
Expand All @@ -216,12 +258,42 @@ def _check_typedep(decl, typedecl, types, knowntypes):
elif decl.kind is KIND.VARIABLE:
if not is_process_global(decl):
return None
if _is_kwlist(decl):
return None
if _has_other_supported_type(decl):
return None
checked = _check_vartype(decl, typedecl, types, knowntypes)
return 'mutable' if checked is FIXED_TYPE else checked
else:
raise NotImplementedError(decl)


def _is_kwlist(decl):
# keywords for PyArg_ParseTupleAndKeywords()
# "static char *name[]" -> "static const char * const name[]"
# XXX These should be made const.
for relpath, name in _KWLIST_VARIANTS:
if decl.name == name:
if relpath == '*':
break
assert os.path.isabs(decl.file.filename)
relpath = os.path.normpath(relpath)
if decl.file.filename.endswith(os.path.sep + relpath):
break
else:
return False
vartype = ''.join(str(decl.vartype).split())
return vartype == 'char*[]'


def _has_other_supported_type(decl):
vartype = str(decl.vartype).split()
if vartype[0] == 'struct':
vartype = vartype[1:]
vartype = ''.join(vartype)
return vartype in _OTHER_SUPPORTED_TYPES


def _check_vartype(decl, typedecl, types, knowntypes):
"""Return failure reason."""
checked = _check_typespec(decl, typedecl, types, knowntypes)
Expand Down
4 changes: 3 additions & 1 deletion Tools/c-analyzer/cpython/globals-to-fix.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ Objects/typeobject.c - next_version_tag -
Objects/typeobject.c resolve_slotdups ptrs -
Parser/pegen.c - memo_statistics -
Python/bootstrap_hash.c - urandom_cache -
Python/ceval.c make_pending_calls busy -
Python/ceval_gil.c make_pending_calls busy -
Python/ceval.c _PyEval_SetProfile reentrant -
Python/ceval.c _PyEval_SetTrace reentrant -
Python/import.c - import_lock_level -
Expand Down Expand Up @@ -534,6 +534,8 @@ Modules/_io/winconsoleio.c - _PyWindowsConsoleIO_Type -
# initialized once
Modules/_functoolsmodule.c - kwd_mark -
Modules/_io/_iomodule.c - _PyIO_empty_bytes -
Modules/_testcapi/heaptype.c - _testcapimodule -
Modules/_testcapi/unicode.c - _testcapimodule -
Modules/_tracemalloc.c - tracemalloc_empty_traceback -
Modules/signalmodule.c - DefaultHandler -
Modules/signalmodule.c - IgnoreHandler -
Expand Down
Loading