Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r982f95d rd286cf68  
    2121#include <list>                    // for _List_iterator, list, _List_const_...
    2222#include <map>                     // for _Rb_tree_iterator, map, _Rb_tree_c...
    23 #include <memory>                  // for allocator_traits<>::value_type
     23#include <memory>                  // for allocator_traits<>::value_type, unique_ptr
    2424#include <utility>                 // for pair
    2525#include <vector>                  // for vector
     
    3535#include "ResolveTypeof.h"         // for resolveTypeof
    3636#include "Resolver.h"              // for resolveStmtExpr
    37 #include "Common/GC.h"             // for new_static_root
    3837#include "SymTab/Indexer.h"        // for Indexer
    3938#include "SymTab/Mangler.h"        // for Mangler
     
    9897                void postvisit( InitExpr * initExpr );
    9998                void postvisit( DeletedExpr * delExpr );
     99                void postvisit( GenericExpr * genExpr );
    100100
    101101                /// Adds alternatives for anonymous members
     
    166166                                        candidate->env.apply( newType );
    167167                                        mangleName = SymTab::Mangler::mangle( newType );
     168                                        delete newType;
    168169                                }
    169170                                std::map< std::string, PruneStruct >::iterator mapPlace = selected.find( mangleName );
     
    175176                                                selected[ mangleName ] = current;
    176177                                        } else if ( candidate->cost == mapPlace->second.candidate->cost ) {
    177                                                 PRINT(
    178                                                         std::cerr << "marking ambiguous" << std::endl;
    179                                                 )
    180                                                 mapPlace->second.isAmbiguous = true;
     178                                                // if one of the candidates contains a deleted identifier, can pick the other, since
     179                                                // deleted expressions should not be ambiguous if there is another option that is at least as good
     180                                                if ( findDeletedExpr( candidate->expr ) ) {
     181                                                        // do nothing
     182                                                        PRINT( std::cerr << "candidate is deleted" << std::endl; )
     183                                                } else if ( findDeletedExpr( mapPlace->second.candidate->expr ) ) {
     184                                                        PRINT( std::cerr << "current is deleted" << std::endl; )
     185                                                        selected[ mangleName ] = current;
     186                                                } else {
     187                                                        PRINT(
     188                                                                std::cerr << "marking ambiguous" << std::endl;
     189                                                        )
     190                                                        mapPlace->second.isAmbiguous = true;
     191                                                }
    181192                                        } else {
    182193                                                PRINT(
     
    233244        }
    234245
    235         void AlternativeFinder::find( Expression *expr, ResolvMode mode ) {
     246        void AlternativeFinder::find( Expression *expr, bool adjust, bool prune, bool failFast ) {
    236247                PassVisitor<Finder> finder( *this );
    237248                expr->accept( finder );
    238                 if ( mode.failFast && alternatives.empty() ) {
     249                if ( failFast && alternatives.empty() ) {
    239250                        PRINT(
    240251                                std::cerr << "No reasonable alternatives for expression " << expr << std::endl;
     
    242253                        SemanticError( expr, "No reasonable alternatives for expression " );
    243254                }
    244                 if ( mode.prune ) {
     255                if ( prune ) {
    245256                        auto oldsize = alternatives.size();
    246257                        PRINT(
     
    250261                        AltList pruned;
    251262                        pruneAlternatives( alternatives.begin(), alternatives.end(), back_inserter( pruned ) );
    252                         if ( mode.failFast && pruned.empty() ) {
     263                        if ( failFast && pruned.empty() ) {
    253264                                std::ostringstream stream;
    254265                                AltList winners;
     
    269280                }
    270281                // adjust types after pruning so that types substituted by pruneAlternatives are correctly adjusted
    271                 if ( mode.adjust ) {
    272                         for ( Alternative& i : alternatives ) {
    273                                 adjustExprType( i.expr->result, i.env, indexer );
     282                for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
     283                        if ( adjust ) {
     284                                adjustExprType( i->expr->get_result(), i->env, indexer );
    274285                        }
    275286                }
     
    283294
    284295        void AlternativeFinder::findWithAdjustment( Expression *expr ) {
    285                 find( expr, ResolvMode::withAdjustment() );
     296                find( expr, true );
    286297        }
    287298
    288299        void AlternativeFinder::findWithoutPrune( Expression * expr ) {
    289                 find( expr, ResolvMode::withoutPrune() );
     300                find( expr, true, false );
    290301        }
    291302
    292303        void AlternativeFinder::maybeFind( Expression * expr ) {
    293                 find( expr, ResolvMode::withoutFailFast() );
     304                find( expr, true, true, false );
    294305        }
    295306
     
    297308                // adds anonymous member interpretations whenever an aggregate value type is seen.
    298309                // it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value
    299                 Expression* aggrExpr = alt.expr->clone();
    300                 alt.env.apply( aggrExpr->get_result() );
    301                 Type * aggrType = aggrExpr->get_result();
     310                std::unique_ptr<Expression> aggrExpr( alt.expr->clone() );
     311                alt.env.apply( aggrExpr->result );
     312                Type * aggrType = aggrExpr->result;
    302313                if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
    303314                        aggrType = aggrType->stripReferences();
    304                         aggrExpr = new CastExpr{ aggrExpr, aggrType->clone() };
    305                 }
    306 
    307                 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
    308                         addAggMembers( structInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
    309                 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
    310                         addAggMembers( unionInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
     315                        aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );
     316                }
     317
     318                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
     319                        addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
     320                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
     321                        addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
    311322                } // if
    312323        }
     
    317328                aggInst->lookup( name, members );
    318329
    319                 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    320                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    321                                 alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
    322                                 renameTypes( alternatives.back().expr );
    323                                 addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
     330                for ( Declaration * decl : members ) {
     331                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
     332                                // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
     333                                // can't construct in place and use vector::back
     334                                Alternative newAlt( new MemberExpr( dwt, expr->clone() ), env, newCost );
     335                                renameTypes( newAlt.expr );
     336                                addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
     337                                alternatives.push_back( std::move(newAlt) );
    324338                        } else {
    325339                                assert( false );
     
    331345                if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    332346                        // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
    333                         // xxx - this should be improved by memoizing the value of constant exprs
    334                         // during parsing and reusing that information here.
    335                         std::stringstream ss( constantExpr->get_constant()->get_value() );
    336                         int val = 0;
     347                        auto val = constantExpr->intValue();
    337348                        std::string tmp;
    338                         if ( ss >> val && ! (ss >> tmp) ) {
    339                                 if ( val >= 0 && (unsigned int)val < tupleType->size() ) {
    340                                         alternatives.push_back( Alternative( new TupleIndexExpr( expr, val ), env, newCost ) );
    341                                 } // if
     349                        if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
     350                                alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    342351                        } // if
    343                 } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {
    344                         // xxx - temporary hack until 0/1 are int constants
    345                         if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
    346                                 std::stringstream ss( nameExpr->get_name() );
    347                                 int val;
    348                                 ss >> val;
    349                                 alternatives.push_back( Alternative( new TupleIndexExpr( expr, val ), env, newCost ) );
    350                         }
    351352                } // if
    352353        }
    353354
    354355        void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) {
    355                 alternatives.push_back( Alternative( applicationExpr, env, Cost::zero ) );
     356                alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
    356357        }
    357358
     
    435436                                        return Cost::infinity;
    436437                                }
     438                        }
     439                        if ( DefaultArgExpr * def = dynamic_cast< DefaultArgExpr * >( *actualExpr ) ) {
     440                                // default arguments should be free - don't include conversion cost.
     441                                // Unwrap them here because they are not relevant to the rest of the system.
     442                                *actualExpr = def->expr;
     443                                ++formal;
     444                                continue;
    437445                        }
    438446                        Type * formalType = (*formal)->get_type();
     
    552560
    553561                                Expression *varExpr = data.combine( newerAlt.cvtCost );
     562                                delete varExpr->get_result();
    554563                                varExpr->set_result( adjType->clone() );
    555564                                PRINT(
     
    565574                                        inferParameters = (*inferParameters)[ id ].inferParams.get();
    566575                                }
    567                                
    568                                 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType, curDecl->get_type(), varExpr );
     576                                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
     577                                (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    569578                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
     579                        } else {
     580                                delete adjType;
    570581                        }
    571582                }
     
    604615        ConstantExpr* getDefaultValue( Initializer* init ) {
    605616                if ( SingleInit* si = dynamic_cast<SingleInit*>( init ) ) {
    606                         if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->get_value() ) ) {
    607                                 return dynamic_cast<ConstantExpr*>( ce->get_arg() );
     617                        if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->value ) ) {
     618                                return dynamic_cast<ConstantExpr*>( ce->arg );
     619                        } else {
     620                                return dynamic_cast<ConstantExpr*>( si->value );
    608621                        }
    609622                }
     
    614627        struct ArgPack {
    615628                std::size_t parent;                ///< Index of parent pack
    616                 Expression* expr;                  ///< The argument stored here
     629                std::unique_ptr<Expression> expr;  ///< The argument stored here
    617630                Cost cost;                         ///< The cost of this argument
    618631                TypeEnvironment env;               ///< Environment for this pack
     
    626639
    627640                ArgPack()
    628                         : parent(0), expr(nullptr), cost(Cost::zero), env(), need(), have(), openVars(),
    629                           nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {}
     641                        : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0),
     642                          tupleStart(0), nextExpl(0), explAlt(0) {}
    630643
    631644                ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have,
    632645                                const OpenVarSet& openVars)
    633                         : parent(0), expr(nullptr), cost(Cost::zero), env(env), need(need), have(have),
     646                        : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have),
    634647                          openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {}
    635648
     
    638651                                unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0,
    639652                                unsigned explAlt = 0 )
    640                         : parent(parent), expr(expr), cost(cost), env(move(env)), need(move(need)),
     653                        : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)),
    641654                          have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart),
    642655                          nextExpl(nextExpl), explAlt(explAlt) {}
     
    644657                ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have,
    645658                                OpenVarSet&& openVars, unsigned nextArg, Cost added )
    646                         : parent(o.parent), expr(o.expr), cost(o.cost + added), env(move(env)),
    647                           need(move(need)), have(move(have)), openVars(move(openVars)), nextArg(nextArg),
    648                           tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {}
     659                        : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added),
     660                          env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)),
     661                          nextArg(nextArg), tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {}
    649662
    650663                /// true iff this pack is in the middle of an exploded argument
     
    661674                        std::list<Expression*> exprs;
    662675                        const ArgPack* pack = this;
    663                         if ( expr ) { exprs.push_front( expr ); }
     676                        if ( expr ) { exprs.push_front( expr.release() ); }
    664677                        while ( pack->tupleStart == 0 ) {
    665678                                pack = &packs[pack->parent];
    666                                 exprs.push_front( pack->expr );
     679                                exprs.push_front( pack->expr->clone() );
    667680                                cost += pack->cost;
    668681                        }
    669682                        // reset pack to appropriate tuple
    670                         expr = new TupleExpr{ exprs };
     683                        expr.reset( new TupleExpr( exprs ) );
    671684                        tupleStart = pack->tupleStart - 1;
    672685                        parent = pack->parent;
     
    721734
    722735                                                results.emplace_back(
    723                                                         i, expl.exprs[results[i].nextExpl], copy(results[i].env),
     736                                                        i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
    724737                                                        copy(results[i].need), copy(results[i].have),
    725738                                                        copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl,
     
    742755                                                        newResult.parent = i;
    743756                                                        std::list<Expression*> emptyList;
    744                                                         newResult.expr = new TupleExpr{ emptyList };
     757                                                        newResult.expr.reset( new TupleExpr( emptyList ) );
    745758                                                        argType = newResult.expr->get_result();
    746759                                                } else {
     
    749762                                                        newResult.cost = results[i].cost;
    750763                                                        newResult.tupleStart = results[i].tupleStart;
    751                                                         newResult.expr = results[i].expr;
     764                                                        newResult.expr.reset( results[i].expr->clone() );
    752765                                                        argType = newResult.expr->get_result();
    753766
     
    799812                                                // add new result
    800813                                                results.emplace_back(
    801                                                         i, expl.exprs.front(), move(env), copy(results[i].need),
     814                                                        i, expl.exprs.front().get(), move(env), copy(results[i].need),
    802815                                                        copy(results[i].have), move(openVars), nextArg + 1,
    803816                                                        nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     
    825838                        if ( results[i].hasExpl() ) {
    826839                                const ExplodedActual& expl = results[i].getExpl( args );
    827                                 Expression* expr = expl.exprs[results[i].nextExpl];
     840                                Expression* expr = expl.exprs[results[i].nextExpl].get();
    828841
    829842                                TypeEnvironment env = results[i].env;
     
    866879                                                                indexer ) ) {
    867880                                                        results.emplace_back(
    868                                                                 i, cnstExpr, move(env), move(need), move(have),
     881                                                                i, new DefaultArgExpr( cnstExpr ), move(env), move(need), move(have),
    869882                                                                move(openVars), nextArg, nTuples );
    870883                                                }
     
    896909
    897910                                // consider only first exploded actual
    898                                 Expression* expr = expl.exprs.front();
     911                                Expression* expr = expl.exprs.front().get();
    899912                                Type* actualType = expr->result->clone();
    900913
     
    924937
    925938        template<typename OutputIterator>
    926         void AlternativeFinder::Finder::validateFunctionAlternative( const Alternative &func,
    927                         ArgPack& result, const std::vector<ArgPack>& results, OutputIterator out ) {
    928                 ApplicationExpr *appExpr = new ApplicationExpr( func.expr );
     939        void AlternativeFinder::Finder::validateFunctionAlternative( const Alternative &func, ArgPack& result,
     940                        const std::vector<ArgPack>& results, OutputIterator out ) {
     941                ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
    929942                // sum cost and accumulate actuals
    930943                std::list<Expression*>& args = appExpr->args;
     
    932945                const ArgPack* pack = &result;
    933946                while ( pack->expr ) {
    934                         args.push_front( pack->expr );
     947                        args.push_front( pack->expr->clone() );
    935948                        cost += pack->cost;
    936949                        pack = &results[pack->parent];
     
    9991012
    10001013                                                results.emplace_back(
    1001                                                         i, expl.exprs[results[i].nextExpl], copy(results[i].env),
     1014                                                        i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
    10021015                                                        copy(results[i].need), copy(results[i].have),
    10031016                                                        copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl,
     
    10351048                                                // add new result
    10361049                                                results.emplace_back(
    1037                                                         i, expl.exprs.front(), move(env), copy(results[i].need),
     1050                                                        i, expl.exprs.front().get(), move(env), copy(results[i].need),
    10381051                                                        copy(results[i].have), move(openVars), nextArg + 1, 0,
    10391052                                                        expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     
    10581071                funcFinder.findWithAdjustment( untypedExpr->function );
    10591072                // if there are no function alternatives, then proceeding is a waste of time.
     1073                // xxx - findWithAdjustment throws, so this check and others like it shouldn't be necessary.
    10601074                if ( funcFinder.alternatives.empty() ) return;
    10611075
     
    10691083
    10701084                // find function operators
    1071                 static auto *opExpr = new_static_root<NameExpr>( "?()" );
     1085                static NameExpr *opExpr = new NameExpr( "?()" );
    10721086                AlternativeFinder funcOpFinder( indexer, env );
    10731087                // it's ok if there aren't any defined function ops
     
    10851099                        argExpansions.emplace_back();
    10861100                        auto& argE = argExpansions.back();
    1087                         argE.reserve( arg.alternatives.size() );
     1101                        // argE.reserve( arg.alternatives.size() );
    10881102
    10891103                        for ( const Alternative& actual : arg ) {
     
    11011115                                )
    11021116                                // check if the type is pointer to function
    1103                                 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
    1104                                         if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     1117                                if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->result->stripReferences() ) ) {
     1118                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->base ) ) {
    11051119                                                Alternative newFunc( *func );
    11061120                                                referenceToRvalueConversion( newFunc.expr, newFunc.cost );
     
    11081122                                                        std::back_inserter( candidates ) );
    11091123                                        }
    1110                                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
    1111                                         if ( ClassRef eqvClass = func->env.lookup( typeInst->get_name() ) ) {
    1112                                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.get_bound().type ) ) {
     1124                                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
     1125                                        if ( const EqvClass *eqvClass = func->env.lookup( typeInst->name ) ) {
     1126                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass->type ) ) {
    11131127                                                        Alternative newFunc( *func );
    11141128                                                        referenceToRvalueConversion( newFunc.expr, newFunc.cost );
     
    11381152                                        // check if type is a pointer to function
    11391153                                        if ( PointerType* pointer = dynamic_cast<PointerType*>(
    1140                                                         funcOp->expr->get_result()->stripReferences() ) ) {
     1154                                                        funcOp->expr->result->stripReferences() ) ) {
    11411155                                                if ( FunctionType* function =
    1142                                                                 dynamic_cast<FunctionType*>( pointer->get_base() ) ) {
     1156                                                                dynamic_cast<FunctionType*>( pointer->base ) ) {
    11431157                                                        Alternative newFunc( *funcOp );
    11441158                                                        referenceToRvalueConversion( newFunc.expr, newFunc.cost );
     
    11621176                        PRINT(
    11631177                                ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc.expr );
    1164                                 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    1165                                 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->get_base() );
    1166                                 std::cerr << "Case +++++++++++++ " << appExpr->get_function() << std::endl;
     1178                                PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->function->result );
     1179                                FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->base );
     1180                                std::cerr << "Case +++++++++++++ " << appExpr->function << std::endl;
    11671181                                std::cerr << "formals are:" << std::endl;
    1168                                 printAll( function->get_parameters(), std::cerr, 8 );
     1182                                printAll( function->parameters, std::cerr, 8 );
    11691183                                std::cerr << "actuals are:" << std::endl;
    1170                                 printAll( appExpr->get_args(), std::cerr, 8 );
     1184                                printAll( appExpr->args, std::cerr, 8 );
    11711185                                std::cerr << "bindings are:" << std::endl;
    11721186                                withFunc.env.print( std::cerr, 8 );
     
    12091223        bool isLvalue( Expression *expr ) {
    12101224                // xxx - recurse into tuples?
    1211                 return expr->result && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
     1225                return expr->result && ( expr->result->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) );
    12121226        }
    12131227
     
    12181232                        if ( isLvalue( alt.expr ) ) {
    12191233                                alternatives.push_back(
    1220                                         Alternative{ new AddressExpr( alt.expr ), alt.env, alt.cost } );
     1234                                        Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } );
    12211235                        } // if
    12221236                } // for
     
    12241238
    12251239        void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) {
    1226                 alternatives.push_back( Alternative{ expr, env, Cost::zero } );
     1240                alternatives.push_back( Alternative{ expr->clone(), env, Cost::zero } );
    12271241        }
    12281242
     
    12441258                                componentExprs.push_back( restructureCast( idx, toType->getComponent( i ), isGenerated ) );
    12451259                        }
     1260                        delete argExpr;
    12461261                        assert( componentExprs.size() > 0 );
    12471262                        // produce the tuple of casts
     
    13191334                for ( Alternative & alt : finder.alternatives ) {
    13201335                        alternatives.push_back( Alternative(
    1321                                 new VirtualCastExpr( alt.expr, castExpr->get_result()->clone() ),
     1336                                new VirtualCastExpr( alt.expr->clone(), castExpr->get_result()->clone() ),
    13221337                                alt.env, alt.cost ) );
    13231338                }
     
    13411356                        Expression * aggrExpr = agg->expr->clone();
    13421357                        referenceToRvalueConversion( aggrExpr, cost );
     1358                        std::unique_ptr<Expression> guard( aggrExpr );
    13431359
    13441360                        // find member of the given type
     
    13541370
    13551371        void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) {
    1356                 alternatives.push_back( Alternative( memberExpr, env, Cost::zero ) );
     1372                alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) );
    13571373        }
    13581374
     
    13641380                        Cost cost = Cost::zero;
    13651381                        Expression * newExpr = data.combine( cost );
    1366                         alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) );
     1382
     1383                        // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
     1384                        // can't construct in place and use vector::back
     1385                        Alternative newAlt( newExpr, env, Cost::zero, cost );
    13671386                        PRINT(
    13681387                                std::cerr << "decl is ";
     
    13731392                                std::cerr << std::endl;
    13741393                        )
    1375                         renameTypes( alternatives.back().expr );
    1376                         addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
     1394                        renameTypes( newAlt.expr );
     1395                        addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
     1396                        alternatives.push_back( std::move(newAlt) );
    13771397                } // for
    13781398        }
     
    13851405
    13861406        void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) {
    1387                 alternatives.push_back( Alternative( constantExpr, env, Cost::zero ) );
     1407                alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) );
    13881408        }
    13891409
     
    14051425                        Alternative &choice = winners.front();
    14061426                        referenceToRvalueConversion( choice.expr, choice.cost );
    1407                         alternatives.push_back( Alternative( new SizeofExpr( choice.expr ), choice.env, Cost::zero ) );
     1427                        alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
    14081428                } // if
    14091429        }
     
    14261446                        Alternative &choice = winners.front();
    14271447                        referenceToRvalueConversion( choice.expr, choice.cost );
    1428                         alternatives.push_back( Alternative( new AlignofExpr( choice.expr ), choice.env, Cost::zero ) );
     1448                        alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
    14291449                } // if
    14301450        }
     
    14551475
    14561476        void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) {
    1457                 alternatives.push_back( Alternative( offsetofExpr, env, Cost::zero ) );
     1477                alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) );
    14581478        }
    14591479
    14601480        void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) {
    1461                 alternatives.push_back( Alternative( offsetPackExpr, env, Cost::zero ) );
     1481                alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) );
    14621482        }
    14631483
     
    15371557                                compositeEnv.simpleCombine( second.env );
    15381558
    1539                                 LogicalExpr *newExpr = new LogicalExpr( first.expr, second.expr, logicalExpr->get_isAnd() );
     1559                                LogicalExpr *newExpr = new LogicalExpr( first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() );
    15401560                                alternatives.push_back( Alternative( newExpr, compositeEnv, first.cost + second.cost ) );
    15411561                        }
     
    15701590                                        Type* commonType = nullptr;
    15711591                                        if ( unify( second.expr->result, third.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    1572                                                 ConditionalExpr *newExpr = new ConditionalExpr( first.expr, second.expr, third.expr );
     1592                                                ConditionalExpr *newExpr = new ConditionalExpr( first.expr->clone(), second.expr->clone(), third.expr->clone() );
    15731593                                                newExpr->result = commonType ? commonType : second.expr->result->clone();
    15741594                                                // convert both options to the conditional result type
     
    15891609                secondFinder.findWithAdjustment( commaExpr->get_arg2() );
    15901610                for ( const Alternative & alt : secondFinder.alternatives ) {
    1591                         alternatives.push_back( Alternative( new CommaExpr( newFirstArg, alt.expr ), alt.env, alt.cost ) );
     1611                        alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt.expr->clone() ), alt.env, alt.cost ) );
    15921612                } // for
     1613                delete newFirstArg;
    15931614        }
    15941615
     
    16111632                                Type* commonType = nullptr;
    16121633                                if ( unify( first.expr->result, second.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    1613                                         RangeExpr * newExpr = new RangeExpr( first.expr, second.expr );
     1634                                        RangeExpr * newExpr = new RangeExpr( first.expr->clone(), second.expr->clone() );
    16141635                                        newExpr->result = commonType ? commonType : first.expr->result->clone();
    16151636                                        newAlt.expr = newExpr;
     
    16391660
    16401661        void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) {
    1641                 alternatives.push_back( Alternative( tupleExpr, env, Cost::zero ) );
     1662                alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
    16421663        }
    16431664
    16441665        void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    1645                 alternatives.push_back( Alternative( impCpCtorExpr, env, Cost::zero ) );
     1666                alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) );
    16461667        }
    16471668
     
    16521673                finder.findWithoutPrune( ctorExpr->get_callExpr() );
    16531674                for ( Alternative & alt : finder.alternatives ) {
    1654                         alternatives.push_back( Alternative( new ConstructorExpr( alt.expr ), alt.env, alt.cost ) );
     1675                        alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) );
    16551676                }
    16561677        }
    16571678
    16581679        void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) {
    1659                 alternatives.push_back( Alternative( tupleExpr, env, Cost::zero ) );
     1680                alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
    16601681        }
    16611682
    16621683        void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) {
    1663                 alternatives.push_back( Alternative( tupleAssignExpr, env, Cost::zero ) );
     1684                alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
    16641685        }
    16651686
     
    16691690                for ( Alternative & alt : finder.alternatives ) {
    16701691                        // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked"
    1671                         UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr, unqExpr->get_id() );
     1692                        UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() );
    16721693                        alternatives.push_back( Alternative( newUnqExpr, alt.env, alt.cost ) );
    16731694                }
     
    17201741                                        // count one safe conversion for each value that is thrown away
    17211742                                        thisCost.incSafe( discardedValues );
    1722                                         Alternative newAlt( new InitExpr( restructureCast( alt.expr, toType, true ), initAlt.designation ), newEnv, alt.cost, thisCost );
     1743                                        Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost );
    17231744                                        inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    17241745                                }
     
    17411762                assertf( false, "AlternativeFinder should never see a DeletedExpr." );
    17421763        }
     1764
     1765        void AlternativeFinder::Finder::postvisit( GenericExpr * ) {
     1766                assertf( false, "_Generic is not yet supported." );
     1767        }
    17431768} // namespace ResolvExpr
    17441769
Note: See TracChangeset for help on using the changeset viewer.