#   Copyright 2013-2016 Free Software Foundation, Inc.
#
#   This is free software: you can redistribute it and/or modify it
#   under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful, but
#   WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see
#   <http://www.gnu.org/licenses/>.

import gcc
import gccutils
import sys

want_raii_info = False

logging = False
show_cfg = False

def log(msg, indent=0):
    global logging
    if logging:
        sys.stderr.write('%s%s\n' % ('  ' * indent, msg))
        sys.stderr.flush()

def is_cleanup_type(return_type):
    if not isinstance(return_type, gcc.PointerType):
        return False
    if not isinstance(return_type.dereference, gcc.RecordType):
        return False
    if str(return_type.dereference.name) == 'cleanup':
        return True
    return False

def is_constructor(decl):
    "Return True if the function DECL is a cleanup constructor; False otherwise"
    return is_cleanup_type(decl.type.type) and (not decl.name or str(decl.name) != 'make_final_cleanup')

destructor_names = set(['do_cleanups', 'discard_cleanups'])

def is_destructor(decl):
    return decl.name in destructor_names

# This list is just much too long... we should probably have an
# attribute instead.
special_names = set(['do_final_cleanups', 'discard_final_cleanups',
                     'save_cleanups', 'save_final_cleanups',
                     'restore_cleanups', 'restore_final_cleanups',
                     'exceptions_state_mc_init',
                     'make_my_cleanup2', 'make_final_cleanup', 'all_cleanups',
                     'save_my_cleanups', 'quit_target'])

def needs_special_treatment(decl):
    return decl.name in special_names

# Sometimes we need a new placeholder object that isn't the same as
# anything else.
class Dummy(object):
    def __init__(self, location):
        self.location = location

# A wrapper for a cleanup which has been assigned to a variable.
# This holds the variable and the location.
class Cleanup(object):
    def __init__(self, var, location):
        self.var = var
        self.location = location

# A class representing a master cleanup.  This holds a stack of
# cleanup objects and supports a merging operation.
class MasterCleanup(object):
    # Create a new MasterCleanup object.  OTHER, if given, is a
    # MasterCleanup object to copy.
    def __init__(self, other = None):
        # 'cleanups' is a list of cleanups.  Each element is either a
        # Dummy, for an anonymous cleanup, or a Cleanup, for a cleanup
        # which was assigned to a variable.
        if other is None:
            self.cleanups = []
            self.aliases = {}
        else:
            self.cleanups = other.cleanups[:]
            self.aliases = dict(other.aliases)

    def compare_vars(self, definition, argument):
        if definition == argument:
            return True
        if argument in self.aliases:
            argument = self.aliases[argument]
        if definition in self.aliases:
            definition = self.aliases[definition]
        return definition == argument

    def note_assignment(self, lhs, rhs):
        log('noting assignment %s = %s' % (lhs, rhs), 4)
        self.aliases[lhs] = rhs

    # Merge with another MasterCleanup.
    # Returns True if this resulted in a change to our state.
    def merge(self, other):
        # We do explicit iteration like this so we can easily
        # update the list after the loop.
        counter = -1
        found_named = False
        for counter in range(len(self.cleanups) - 1, -1, -1):
            var = self.cleanups[counter]
            log('merge checking %s' % var, 4)
            # Only interested in named cleanups.
            if isinstance(var, Dummy):
                log('=> merge dummy', 5)
                continue
            # Now see if VAR is found in OTHER.
            if other._find_var(var.var) >= 0:
                log ('=> merge found', 5)
                break
            log('=>merge not found', 5)
            found_named = True
        if found_named and counter < len(self.cleanups) - 1:
            log ('merging to %d' % counter, 4)
            if counter < 0:
                self.cleanups = []
            else:
                self.cleanups = self.cleanups[0:counter]
            return True
        # If SELF is empty but OTHER has some cleanups, then consider
        # that a change as well.
        if len(self.cleanups) == 0 and len(other.cleanups) > 0:
            log('merging non-empty other', 4)
            self.cleanups = other.cleanups[:]
            return True
        return False

    # Push a new constructor onto our stack.  LHS is the
    # left-hand-side of the GimpleCall statement.  It may be None,
    # meaning that this constructor's value wasn't used.
    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)

    # A helper for merge and pop that finds BACK_TO in self.cleanups,
    # and returns the index, or -1 if not found.
    def _find_var(self, back_to):
        for i in range(len(self.cleanups) - 1, -1, -1):
            if isinstance(self.cleanups[i], Dummy):
                continue
            if self.compare_vars(self.cleanups[i].var, back_to):
                return i
        return -1

    # Pop constructors until we find one matching BACK_TO.
    # This is invoked when we see a do_cleanups call.
    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')

    # Check whether ARG is the current master cleanup.  Return True if
    # all is well.
    def verify(self, location, arg):
        log('verify %s' % arg, 4)
        return (len(self.cleanups) > 0
                and not isinstance(self.cleanups[0], Dummy)
                and self.compare_vars(self.cleanups[0].var, arg))

    # Check whether SELF is empty.
    def isempty(self):
        log('isempty: len = %d' % len(self.cleanups), 4)
        return len(self.cleanups) == 0

    # Emit informational warnings about the cleanup stack.
    def inform(self):
        for item in reversed(self.cleanups):
            gcc.inform(item.location, 'leaked cleanup')

class CleanupChecker:
    def __init__(self, fun):
        self.fun = fun
        self.seen_edges = set()
        self.bad_returns = set()

        # This maps BB indices to a list of master cleanups for the
        # BB.
        self.master_cleanups = {}

    # Pick a reasonable location for the basic block BB.
    def guess_bb_location(self, bb):
        if isinstance(bb.gimple, list):
            for stmt in bb.gimple:
                if stmt.loc:
                    return stmt.loc
        return self.fun.end

    # Compute the master cleanup list for BB.
    # Modifies MASTER_CLEANUP in place.
    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()

    # Traverse a basic block, updating the master cleanup information
    # and propagating to other blocks.
    def traverse_bbs(self, edge, bb, bb_from, entry_master):
        log('traverse_bbs %d from %d' % (bb.index, bb_from), 1)

        # Propagate the entry MasterCleanup though this block.
        master_cleanup = MasterCleanup(entry_master)
        self.compute_master(bb, bb_from, master_cleanup)

        modified = False
        if bb.index in self.master_cleanups:
            # Merge the newly-computed MasterCleanup into the one we
            # have already computed.  If this resulted in a
            # significant change, then we need to re-propagate.
            modified = self.master_cleanups[bb.index].merge(master_cleanup)
        else:
            self.master_cleanups[bb.index] = master_cleanup
            modified = True

        # EDGE is None for the entry BB.
        if edge is not None:
            # If merging cleanups caused a change, check to see if we
            # have a bad loop.
            if edge in self.seen_edges:
                # This error doesn't really help.
                # if modified:
                #     gcc.permerror(self.guess_bb_location(bb),
                #                   'invalid cleanup use in loop')
                return
            self.seen_edges.add(edge)

        if not modified:
            return

        # Now propagate to successor nodes.
        for edge in bb.succs:
            self.traverse_bbs(edge, edge.dest, bb.index, master_cleanup)

    def check_cleanups(self):
        if not self.fun.cfg or not self.fun.decl:
            return 'ignored'
        if is_destructor(self.fun.decl):
            return 'destructor'
        if needs_special_treatment(self.fun.decl):
            return 'special'

        self.is_constructor = is_constructor(self.fun.decl)
        self.is_special_constructor = not self.is_constructor and str(self.fun.decl.name).find('with_cleanup') > -1
        # Yuck.
        if str(self.fun.decl.name) == 'gdb_xml_create_parser_and_cleanup_1':
            self.is_special_constructor = True

        if self.is_special_constructor:
            gcc.inform(self.fun.start, 'function %s is a special constructor' % (self.fun.decl.name))

        # If we only see do_cleanups calls, and this function is not
        # itself a constructor, then we can convert it easily to RAII.
        self.only_do_cleanups_seen = not self.is_constructor
        # If we ever call a constructor, then we are "cleanup-aware".
        self.cleanup_aware = False

        entry_bb = self.fun.cfg.entry
        master_cleanup = MasterCleanup()
        self.traverse_bbs(None, entry_bb, -1, master_cleanup)
        if want_raii_info and self.only_do_cleanups_seen and self.cleanup_aware:
            gcc.inform(self.fun.decl.location,
                       'function %s could be converted to RAII' % (self.fun.decl.name))
        if self.is_constructor:
            return 'constructor'
        return 'OK'

class CheckerPass(gcc.GimplePass):
    def execute(self, fun):
        if fun.decl:
            log("Starting " + fun.decl.name)
            if show_cfg:
                dot = gccutils.cfg_to_dot(fun.cfg, fun.decl.name)
                gccutils.invoke_dot(dot, name=fun.decl.name)
        checker = CleanupChecker(fun)
        what = checker.check_cleanups()
        if fun.decl:
            log(fun.decl.name + ': ' + what, 2)

ps = CheckerPass(name = 'check-cleanups')
# We need the cfg, but we want a relatively high-level Gimple.
ps.register_after('cfg')
