Changeset 2c187378


Ignore:
Timestamp:
Oct 17, 2018, 4:16:18 PM (3 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer
Children:
fbecee5
Parents:
da48183
Message:

Fix memory bugs in deferred resolution

Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Alternative.cc

    rda48183 r2c187378  
    2020#include <utility>                       // for move
    2121
    22 #include "Common/utility.h"              // for maybeClone
     22#include "Common/utility.h"              // for cloneAll
    2323#include "ResolvExpr/Cost.h"             // for Cost, Cost::zero, operator<<
    2424#include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment
     
    3535        Alternative::Alternative( const Alternative &o, Expression *expr, const Cost &cost )
    3636        : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( o.env ), openVars( o.openVars ),
    37           need( o.need ) {}
     37          need() { cloneAll( o.need, need ); }
    3838
    3939        Alternative::Alternative( Expression *expr, const TypeEnvironment &env,
    40                 const OpenVarSet& openVars, const AssertionList& need, const Cost& cost )
     40                const OpenVarSet& openVars, const AssertionList& oneed, const Cost& cost )
    4141        : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ), openVars( openVars ),
    42           need( need ) {}
     42          need() { cloneAll( oneed, need ); }
    4343
    4444        Alternative::Alternative( Expression *expr, const TypeEnvironment &env,
    45                 const OpenVarSet& openVars, const AssertionList& need, const Cost& cost,
     45                const OpenVarSet& openVars, const AssertionList& oneed, const Cost& cost,
    4646                const Cost &cvtCost )
    4747        : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ), openVars( openVars ),
    48           need( need ) {}
     48          need() { cloneAll( oneed, need ); }
     49       
     50        Alternative::Alternative( Expression *expr, const TypeEnvironment &env,
     51                const OpenVarSet &openVars, const AssertionSet &oneed, const Cost &cost)
     52        : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ), openVars( openVars ),
     53          need() { cloneAll( oneed, need ); }
     54       
     55        Alternative::Alternative( Expression *expr, const TypeEnvironment &env,
     56                const OpenVarSet &openVars, const AssertionSet &oneed, const Cost &cost,
     57                const Cost& cvtCost )
     58        : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ), openVars( openVars ),
     59          need() { cloneAll( oneed, need ); }
     60       
     61        Alternative::Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars,
     62                AssertionSet &&needSet, const Cost &cost )
     63        : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( std::move(env) ),
     64          openVars( std::move(openVars) ), need( needSet.begin(), needSet.end() ) {}
     65       
     66        Alternative::Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars,
     67                AssertionSet &&needSet, const Cost &cost, const Cost &cvtCost )
     68        : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( std::move(env) ),
     69          openVars( std::move(openVars) ), need( needSet.begin(), needSet.end() ) {}
    4970
    5071        Alternative::Alternative( const Alternative &other )
    5172        : cost( other.cost ), cvtCost( other.cvtCost ), expr( maybeClone( other.expr ) ),
    52           env( other.env ), openVars( other.openVars ), need( other.need ) {}
     73          env( other.env ), openVars( other.openVars ), need() { cloneAll( other.need, need ); }
    5374
    5475        Alternative &Alternative::operator=( const Alternative &other ) {
     
    6081                env = other.env;
    6182                openVars = other.openVars;
    62                 need = other.need;
     83                need.clear();
     84                cloneAll( other.need, need );
    6385                return *this;
    6486        }
     
    6789        : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ),
    6890          env( std::move( other.env ) ), openVars( std::move( other.openVars ) ),
    69           need( std::move( other.need ) ) {
    70                 other.expr = nullptr;
    71         }
     91          need( std::move( other.need ) ) { other.expr = nullptr; }
    7292
    7393        Alternative & Alternative::operator=( Alternative && other ) {
  • src/ResolvExpr/Alternative.h

    rda48183 r2c187378  
    2222#include "TypeEnvironment.h"  // for TypeEnvironment, AssertionSetValue
    2323
     24#include "Common/utility.h"   // for maybeClone
     25
    2426class Expression;
    2527
     
    3537                AssertionItem( const AssertionSet::value_type& e ) : decl(e.first), info(e.second) {}
    3638                operator AssertionSet::value_type () const { return { decl, info }; }
     39
     40                // to support cloneAll
     41                AssertionItem clone() const { return { maybeClone(decl), info }; }
    3742        };
    3843        /// A list of unresolved assertions
    3944        using AssertionList = std::vector<AssertionItem>;
     45
     46        /// Clones an assertion list into an assertion set
     47        static inline void cloneAll( const AssertionList& src, AssertionSet& dst ) {
     48                for ( const AssertionItem& item : src ) {
     49                        dst.emplace( maybeClone(item.decl), item.info );
     50                }
     51        }
     52
     53        /// Clones an assertion set into an assertion list
     54        static inline void cloneAll( const AssertionSet& src, AssertionList& dst ) {
     55                dst.reserve( dst.size() + src.size() );
     56                for ( const auto& entry : src ) {
     57                        dst.emplace_back( maybeClone(entry.first), entry.second );
     58                }
     59        }
     60
     61        /// Clones an assertion list into an assertion list
     62        static inline void cloneAll( const AssertionList& src, AssertionList& dst ) {
     63                dst.reserve( dst.size() + src.size() );
     64                for ( const AssertionItem& item : src ) {
     65                        dst.emplace_back( maybeClone(item.decl), item.info );
     66                }
     67        }
    4068
    4169        /// One option for resolution of an expression
     
    4876                Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet& openVars,
    4977                        const AssertionList& need, const Cost &cost, const Cost &cvtCost );
     78                Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet &openVars,
     79                        const AssertionSet &need, const Cost &cost);
     80                Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet &openVars,
     81                        const AssertionSet &need, const Cost &cost, const Cost& cvtCost );
     82                Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars,
     83                        AssertionSet &&need, const Cost &cost );
     84                Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars,
     85                        AssertionSet &&need, const Cost &cost, const Cost &cvtCost );
    5086                Alternative( const Alternative &other );
    5187                Alternative &operator=( const Alternative &other );
  • src/ResolvExpr/AlternativeFinder.cc

    rda48183 r2c187378  
    962962                }
    963963                // build and validate new alternative
    964                 Alternative newAlt{
    965                         appExpr, result.env, result.openVars,
    966                         AssertionList( result.need.begin(), result.need.end() ), cost };
     964                Alternative newAlt{ appExpr, result.env, result.openVars, result.need, cost };
    967965                PRINT(
    968966                        std::cerr << "instantiate function success: " << appExpr << std::endl;
     
    13301328                                Alternative newAlt{
    13311329                                        restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ),
    1332                                         alt.env, openVars,
    1333                                         AssertionList( needAssertions.begin(), needAssertions.end() ), alt.cost,
    1334                                         thisCost };
     1330                                        alt.env, openVars, needAssertions, alt.cost, thisCost };
    13351331                                inferParameters( needAssertions, haveAssertions, newAlt, openVars,
    13361332                                        back_inserter( candidates ) );
     
    15241520                                Expression * newExpr = data.combine( cost );
    15251521                                alternatives.push_back( Alternative{
    1526                                         new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, AssertionList{}, 
    1527                                         Cost::zero, cost } );
     1522                                        new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{},
     1523                                        AssertionList{}, Cost::zero, cost } );
    15281524                                for ( DeclarationWithType * retVal : function->returnVals ) {
    15291525                                        alternatives.back().expr->result = retVal->get_type()->clone();
     
    15841580                                OpenVarSet openVars{ first.openVars };
    15851581                                mergeOpenVars( openVars, second.openVars );
    1586                                 AssertionList need{ first.need };
    1587                                 need.insert( need.end(), second.need.begin(), second.need.end() );
     1582                                AssertionSet need;
     1583                                cloneAll( first.need, need );
     1584                                cloneAll( second.need, need );
    15881585
    15891586                                LogicalExpr *newExpr = new LogicalExpr{
    15901587                                        first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() };
    15911588                                alternatives.push_back( Alternative{
    1592                                         newExpr, compositeEnv, openVars, need, first.cost + second.cost } );
     1589                                        newExpr, std::move(compositeEnv), std::move(openVars),
     1590                                        AssertionList( need.begin(), need.end() ), first.cost + second.cost } );
    15931591                        }
    15941592                }
     
    16171615                                        mergeOpenVars( openVars, second.openVars );
    16181616                                        mergeOpenVars( openVars, third.openVars );
    1619                                         AssertionSet needAssertions( first.need.begin(), first.need.end() );
    1620                                         needAssertions.insert( second.need.begin(), second.need.end() );
    1621                                         needAssertions.insert( third.need.begin(), third.need.end() );
    1622                                         AssertionSet haveAssertions;
     1617                                        AssertionSet need;
     1618                                        cloneAll( first.need, need );
     1619                                        cloneAll( second.need, need );
     1620                                        cloneAll( third.need, need );
     1621                                        AssertionSet have;
    16231622                                       
    16241623                                        // unify true and false types, then infer parameters to produce new alternatives
    16251624                                        Type* commonType = nullptr;
    16261625                                        if ( unify( second.expr->result, third.expr->result, compositeEnv,
    1627                                                         needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
     1626                                                        need, have, openVars, indexer, commonType ) ) {
    16281627                                                ConditionalExpr *newExpr = new ConditionalExpr{
    16291628                                                        first.expr->clone(), second.expr->clone(), third.expr->clone() };
     
    16371636                                                // output alternative
    16381637                                                Alternative newAlt{
    1639                                                         newExpr, compositeEnv, openVars,
    1640                                                         AssertionList( needAssertions.begin(), needAssertions.end() ), cost };
    1641                                                 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     1638                                                        newExpr, std::move(compositeEnv), std::move(openVars),
     1639                                                        AssertionList( need.begin(), need.end() ), cost };
     1640                                                inferParameters( need, have, newAlt, openVars, back_inserter( alternatives ) );
    16421641                                        } // if
    16431642                                } // for
     
    16721671                                OpenVarSet openVars{ first.openVars };
    16731672                                mergeOpenVars( openVars, second.openVars );
    1674                                 AssertionSet needAssertions( first.need.begin(), first.need.end() );
    1675                                 needAssertions.insert( second.need.begin(), second.need.end() );
    1676                                 AssertionSet haveAssertions;
     1673                                AssertionSet need;
     1674                                cloneAll( first.need, need );
     1675                                cloneAll( second.need, need );
     1676                                AssertionSet have;
    16771677
    16781678                                Type* commonType = nullptr;
    1679                                 if ( unify( first.expr->result, second.expr->result, compositeEnv, needAssertions,
    1680                                                 haveAssertions, openVars, indexer, commonType ) ) {
     1679                                if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have,
     1680                                                openVars, indexer, commonType ) ) {
    16811681                                        RangeExpr * newExpr =
    16821682                                                new RangeExpr{ first.expr->clone(), second.expr->clone() };
    16831683                                        newExpr->result = commonType ? commonType : first.expr->result->clone();
    16841684                                        Alternative newAlt{
    1685                                                 newExpr, compositeEnv, openVars,
    1686                                                 AssertionList( needAssertions.begin(), needAssertions.end() ),
    1687                                                 first.cost + second.cost };
    1688                                         inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     1685                                                newExpr, std::move(compositeEnv), std::move(openVars),
     1686                                                AssertionList( need.begin(), need.end() ), first.cost + second.cost };
     1687                                        inferParameters( need, have, newAlt, openVars, back_inserter( alternatives ) );
    16891688                                } // if
    16901689                        } // for
     
    17091708                                compositeEnv.simpleCombine( alt.env );
    17101709                                mergeOpenVars( openVars, alt.openVars );
    1711                                 need.insert( alt.need.begin(), alt.need.end() );
     1710                                cloneAll( alt.need, need );
    17121711                        }
    17131712                       
    17141713                        alternatives.push_back( Alternative{
    1715                                 new TupleExpr{ exprs }, compositeEnv, openVars,
     1714                                new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars),
    17161715                                AssertionList( need.begin(), need.end() ), sumCost( alts ) } );
    17171716                } // for
     
    17811780                        for ( Alternative & alt : finder.get_alternatives() ) {
    17821781                                TypeEnvironment newEnv( alt.env );
    1783                                 AssertionSet needAssertions( alt.need.begin(), alt.need.end() );
    1784                                 AssertionSet haveAssertions;
     1782                                AssertionSet need;
     1783                                cloneAll( alt.need, need );
     1784                                AssertionSet have;
    17851785                                OpenVarSet openVars( alt.openVars ); 
    17861786                                // xxx - find things in env that don't have a "representative type" and claim
     
    18011801                               
    18021802                                // unification run for side-effects
    1803                                 unify( toType, alt.expr->result, newEnv, needAssertions, haveAssertions, openVars,
    1804                                         indexer );
     1803                                unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer );
    18051804                                // xxx - do some inspecting on this line... why isn't result bound to initAlt.type?
    18061805
     
    18121811                                                new InitExpr{
    18131812                                                        restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() },
    1814                                                 newEnv, openVars,
    1815                                                 AssertionList( needAssertions.begin(), needAssertions.end() ),
    1816                                                 alt.cost, thisCost };
    1817                                         inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
     1813                                                std::move(newEnv), std::move(openVars),
     1814                                                AssertionList( need.begin(), need.end() ), alt.cost, thisCost };
     1815                                        inferParameters( need, have, newAlt, openVars, back_inserter( candidates ) );
    18181816                                }
    18191817                        }
  • src/ResolvExpr/ResolveAssertions.cc

    rda48183 r2c187378  
    166166
    167167                Expression* varExpr = match.cdata.combine( alt.cvtCost );
    168                 varExpr->result = match.adjType;
     168                delete varExpr->result;
     169                varExpr->result = match.adjType->clone();
    169170
    170171                // follow the current assertion's ID chain to find the correct set of inferred parameters
     
    177178
    178179                (*inferParams)[ decl->get_uniqueId() ] = ParamEntry{
    179                                 candidate->get_uniqueId(), match.adjType, decl->get_type(), varExpr };
     180                                candidate->get_uniqueId(), match.adjType, decl->get_type()->clone(), varExpr };
    180181        }
    181182
     
    215216                                matches.emplace_back( cdata, adjType, std::move(newEnv), std::move(have),
    216217                                        std::move(newNeed), std::move(newOpenVars) );
     218                        } else {
     219                                delete adjType;
    217220                        }
    218221                }
  • src/Tuples/TupleAssignment.cc

    rda48183 r2c187378  
    7272                                compositeEnv.simpleCombine( alt.env );
    7373                                ResolvExpr::mergeOpenVars( openVars, alt.openVars );
    74                                 need.insert( alt.need.begin(), alt.need.end() );
     74                                cloneAll( alt.need, need );
    7575                        }
    7676
Note: See TracChangeset for help on using the changeset viewer.