def pop(self, location, back_to): log('pop:', 4) i = self._find_var(back_to) if i >= 0: self.cleanups = self.cleanups[0:i] else: gcc.permerror(location, 'destructor call with unknown argument')
def push(self, location, lhs): if lhs is None: obj = Dummy(location) else: obj = Cleanup(lhs, location) log("pushing %s" % lhs, 4) idx = self._find_var(lhs) if idx >= 0: gcc.permerror(location, "reassigning to known cleanup") gcc.inform(self.cleanups[idx].location, "previous assignment is here") self.cleanups.append(obj)
def push(self, location, lhs): if lhs is None: obj = Dummy(location) else: obj = Cleanup(lhs, location) log('pushing %s' % lhs, 4) idx = self._find_var(lhs) if idx >= 0: gcc.permerror(location, 'reassigning to known cleanup') gcc.inform(self.cleanups[idx].location, 'previous assignment is here') self.cleanups.append(obj)
def compute_master(self, bb, bb_from, master_cleanup): if not isinstance(bb.gimple, list): return curloc = self.fun.end for stmt in bb.gimple: if stmt.loc: curloc = stmt.loc if isinstance(stmt, gcc.GimpleCall) and stmt.fndecl: if is_constructor(stmt.fndecl): log( 'saw constructor %s in bb=%d' % (str(stmt.fndecl), bb.index), 2) self.cleanup_aware = True master_cleanup.push(curloc, stmt.lhs) elif is_destructor(stmt.fndecl): if str(stmt.fndecl.name) != 'do_cleanups': self.only_do_cleanups_seen = False log( 'saw destructor %s in bb=%d, bb_from=%d, argument=%s' % (str(stmt.fndecl.name), bb.index, bb_from, str(stmt.args[0])), 2) master_cleanup.pop(curloc, stmt.args[0]) elif needs_special_treatment(stmt.fndecl): pass # gcc.permerror(curloc, 'function needs special treatment') elif isinstance(stmt, gcc.GimpleAssign): if isinstance(stmt.lhs, gcc.VarDecl) and isinstance( stmt.rhs[0], gcc.VarDecl): master_cleanup.note_assignment(stmt.lhs, stmt.rhs[0]) elif isinstance(stmt, gcc.GimpleReturn): if self.is_constructor: if not master_cleanup.verify(curloc, stmt.retval): gcc.permerror( curloc, 'constructor does not return master cleanup') elif not self.is_special_constructor: if not master_cleanup.isempty(): if curloc not in self.bad_returns: gcc.permerror( curloc, 'cleanup stack is not empty at return') self.bad_returns.add(curloc) master_cleanup.inform()
def compute_master(self, bb, bb_from, master_cleanup): if not isinstance(bb.gimple, list): return curloc = self.fun.end for stmt in bb.gimple: if stmt.loc: curloc = stmt.loc if isinstance(stmt, gcc.GimpleCall) and stmt.fndecl: if is_constructor(stmt.fndecl): log("saw constructor %s in bb=%d" % (str(stmt.fndecl), bb.index), 2) self.cleanup_aware = True master_cleanup.push(curloc, stmt.lhs) elif is_destructor(stmt.fndecl): if str(stmt.fndecl.name) != "do_cleanups": self.only_do_cleanups_seen = False log( "saw destructor %s in bb=%d, bb_from=%d, argument=%s" % (str(stmt.fndecl.name), bb.index, bb_from, str(stmt.args[0])), 2, ) master_cleanup.pop(curloc, stmt.args[0]) elif needs_special_treatment(stmt.fndecl): pass # gcc.permerror(curloc, 'function needs special treatment') elif isinstance(stmt, gcc.GimpleAssign): if isinstance(stmt.lhs, gcc.VarDecl) and isinstance(stmt.rhs[0], gcc.VarDecl): master_cleanup.note_assignment(stmt.lhs, stmt.rhs[0]) elif isinstance(stmt, gcc.GimpleReturn): if self.is_constructor: if not master_cleanup.verify(curloc, stmt.retval): gcc.permerror(curloc, "constructor does not return master cleanup") elif not self.is_special_constructor: if not master_cleanup.isempty(): if curloc not in self.bad_returns: gcc.permerror(curloc, "cleanup stack is not empty at return") self.bad_returns.add(curloc) master_cleanup.inform()