def attribute_callback_type_object_for_typedef(*args): if 0: print('attribute_callback_type_object_for_typedef(%r)' % (args, )) check_isinstance(args[0], gcc.VarDecl) check_isinstance(args[1], gcc.StringCst) typedef_name = args[1].constant register_type_object(args[0], typedef_name)
def get_type_for_typeobject(typeobject): check_isinstance(typeobject, gcc.VarDecl) if typeobject.name not in type_dict: return None type_name = type_dict[typeobject.name] return get_global_typedef(type_name)
def __init__(self, ctor): check_isinstance(ctor, gcc.Constructor) self.ctor = ctor # Mapping from string fieldname to gcc.Tree value: self.fielddict = OrderedDict() for key, tree in ctor.elements: check_isinstance(key, gcc.FieldDecl) self.fielddict[key.name] = tree
def int_field(self, fieldname): """ Extract the initializer for the given field, as an int """ if fieldname not in self.fielddict: return 0 # implicit 0 tree = self.fielddict[fieldname] check_isinstance(tree, gcc.IntegerCst) return tree.constant
def __init__(self, fun): check_isinstance(fun, gcc.Function) self.fun = fun from pygments.styles import get_style_by_name from pygments.formatters import HtmlFormatter # Get ready to use Pygments: style = get_style_by_name('default') self.formatter = HtmlFormatter(classprefix='source_') self.trace_idx = 0
def attribute_callback_for_steals_reference_to_arg(*args): if 0: print('attribute_callback_for_steals_reference_to_arg(%r)' % (args, )) check_isinstance(args[0], gcc.FunctionDecl) check_isinstance(args[1], gcc.IntegerCst) fnname = args[0].name argindex = int(args[1].constant) if fnname in stolen_refs_by_fnname: stolen_refs_by_fnname[fnname].add(argindex) else: stolen_refs_by_fnname[fnname] = set([argindex])
def is_duplicate_of(self, other): check_isinstance(other, Report) # Simplistic equivalence classes for now: # the same function, source location, and message; everything # else can be different if self.fun != other.fun: return False if self.loc != other.loc: return False if self.msg != other.msg: return False return True
def char_ptr_field(self, fieldname): if fieldname not in self.fielddict: return None # implicit NULL tree = self.fielddict[fieldname] if isinstance(tree, gcc.IntegerCst): if tree.constant == 0: return None # NULL # go past casts: if isinstance(tree, gcc.NopExpr): tree = tree.operand check_isinstance(tree, gcc.AddrExpr) check_isinstance(tree.operand, gcc.StringCst) return tree.operand.constant
def verify_any_PyMethodDef_flags(): """ Check all initializers for PyMethodDef arrays. Verify that the flags used match the real signature of the callback function (albeit usually cast to a PyCFunction): http://docs.python.org/c-api/structures.html#PyMethodDef """ methods = get_all_PyMethodDef_initializers() #from pprint import pprint #pprint(methods) for si in methods: if 0: print(si) ml_meth = si.function_ptr_field('ml_meth') ml_flags = si.int_field('ml_flags') if 0: print(' ml_meth: %r' % ml_meth) print(' ml_flags: %r' % ml_flags) check_isinstance(ml_flags, int) if ml_meth is not None: check_isinstance(ml_meth, gcc.FunctionDecl) if ml_flags & METH_KEYWORDS: expargs = 3 exptypemsg = 'expected ml_meth callback of type "PyObject (fn)(someobject *, PyObject *args, PyObject *kwargs)" due to METH_KEYWORDS flag' else: expargs = 2 exptypemsg = 'expected ml_meth callback of type "PyObject (fn)(someobject *, PyObject *)"' actualargs = len(ml_meth.type.argument_types) if expargs != actualargs: gcc.warning( si.get_location(), 'flags do not match callback signature for %r' ' within PyMethodDef table' % ml_meth.name) gcc.inform(si.get_location(), exptypemsg + ' (%s arguments)' % expargs) gcc.inform( si.get_location(), 'actual type of underlying callback: %s' % ml_meth.type + ' (%s arguments)' % actualargs) gcc.inform( si.get_location(), 'see http://docs.python.org/c-api/structures.html#PyMethodDef' )
def function_ptr_field(self, fieldname): """ Extract the initializer for the given field, as a gcc.FunctionDecl, or None for NULL. """ if fieldname not in self.fielddict: return None # implicit NULL tree = self.fielddict[fieldname] # go past casts: if isinstance(tree, gcc.NopExpr): tree = tree.operand if isinstance(tree, gcc.IntegerCst): if tree.constant == 0: return None # NULL check_isinstance(tree, gcc.AddrExpr) return tree.operand
def examine_globals(): global output_file vars = gcc.get_variables() for var in vars: if not isinstance(var.decl, gcc.VarDecl): continue output_file.write("################\n") output_file.write("# Analysis for %s\n" % var.decl.name) if not var.decl.initial: continue if not type_is_pythonic(var.decl.type): continue if isinstance(var.decl.type, gcc.ArrayType): for idx, value in var.decl.initial.elements: examine_struct_fields(value) else: gccutils.check_isinstance(var.decl.type, gcc.RecordType) examine_struct_fields(var.decl.initial)
def verify_any_PyMethodDef_flags(): """ Check all initializers for PyMethodDef arrays. Verify that the flags used match the real signature of the callback function (albeit usually cast to a PyCFunction): http://docs.python.org/c-api/structures.html#PyMethodDef """ methods = get_all_PyMethodDef_initializers() #from pprint import pprint #pprint(methods) for si in methods: if 0: print(si) ml_meth = si.function_ptr_field('ml_meth') ml_flags = si.int_field('ml_flags') if 0: print(' ml_meth: %r' % ml_meth) print(' ml_flags: %r' % ml_flags) check_isinstance(ml_flags, int) if ml_meth is not None: check_isinstance(ml_meth, gcc.FunctionDecl) if ml_flags & METH_KEYWORDS: expargs = 3 exptypemsg = 'expected ml_meth callback of type "PyObject (fn)(someobject *, PyObject *args, PyObject *kwargs)" due to METH_KEYWORDS flag' else: expargs = 2 exptypemsg = 'expected ml_meth callback of type "PyObject (fn)(someobject *, PyObject *)"' actualargs = len(ml_meth.type.argument_types) if expargs != actualargs: gcc.warning(si.get_location(), 'flags do not match callback signature for %r' ' within PyMethodDef table' % ml_meth.name) gcc.inform(si.get_location(), exptypemsg + ' (%s arguments)' % expargs) gcc.inform(si.get_location(), 'actual type of underlying callback: %s' % ml_meth.type + ' (%s arguments)' % actualargs) gcc.inform(si.get_location(), 'see http://docs.python.org/c-api/structures.html#PyMethodDef')
def attribute_callback_for_sets_exception(*args): if 0: print('attribute_callback_for_sets_exception(%r)' % args) check_isinstance(args[0], gcc.FunctionDecl) fnname = args[0].name fnnames_setting_exception.add(fnname)
def attribute_callback_for_returns_borrowed_ref(*args): if 0: print('attribute_callback_for_returns_borrowed_ref(%r)' % args) check_isinstance(args[0], gcc.FunctionDecl) fnname = args[0].name fnnames_returning_borrowed_refs.add(fnname)
def register_type_object(typeobject, typedef): check_isinstance(typeobject, gcc.VarDecl) type_dict[typeobject.name] = typedef