Ignore:
Timestamp:
Aug 25, 2017, 12:11:53 PM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
bf7b9da7
Parents:
135b431 (diff), f676b84 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r135b431 r6b224a52  
    6767
    6868        Cost sumCost( const AltList &in ) {
    69                 Cost total;
     69                Cost total = Cost::zero;
    7070                for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
    7171                        total += i->cost;
     
    144144                        expr->get_result()->accept( global_renamer );
    145145                }
    146         }
     146
     147                void referenceToRvalueConversion( Expression *& expr ) {
     148                        if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
     149                                // cast away reference from expr
     150                                expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );
     151                        }
     152                }
     153        } // namespace
    147154
    148155        template< typename InputIterator, typename OutputIterator >
     
    186193                        if ( alternatives.begin() == oldBegin ) {
    187194                                std::ostringstream stream;
    188                                 stream << "Can't choose between " << alternatives.size() << " alternatives for expression ";
     195                                AltList winners;
     196                                findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
     197                                stream << "Can't choose between " << winners.size() << " alternatives for expression ";
    189198                                expr->print( stream );
    190199                                stream << "Alternatives are:";
    191                                 AltList winners;
    192                                 findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
    193200                                printAlts( winners, stream, 8 );
    194201                                throw SemanticError( stream.str() );
     
    213220        void AlternativeFinder::addAnonConversions( const Alternative & alt ) {
    214221                // adds anonymous member interpretations whenever an aggregate value type is seen.
    215                 Expression * expr = alt.expr->clone();
    216                 std::unique_ptr< Expression > manager( expr ); // RAII for expr
    217                 alt.env.apply( expr->get_result() );
    218                 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( expr->get_result() ) ) {
     222                // 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
     223                std::unique_ptr<Expression> aggrExpr( alt.expr->clone() );
     224                alt.env.apply( aggrExpr->get_result() );
     225                Type * aggrType = aggrExpr->get_result();
     226                if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
     227                        aggrType = aggrType->stripReferences();
     228                        aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );
     229                }
     230
     231                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
    219232                        NameExpr nameExpr( "" );
    220                         addAggMembers( structInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr );
    221                 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( expr->get_result() ) ) {
     233                        addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
     234                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
    222235                        NameExpr nameExpr( "" );
    223                         addAggMembers( unionInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr );
     236                        addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
    224237                } // if
    225238        }
     
    228241        void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
    229242                // by this point, member must be a name expr
    230                 NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member );
     243                NameExpr * nameExpr = dynamic_cast< NameExpr * >( member );
     244                if ( ! nameExpr ) return;
    231245                const std::string & name = nameExpr->get_name();
    232246                std::list< Declaration* > members;
     
    250264                        // during parsing and reusing that information here.
    251265                        std::stringstream ss( constantExpr->get_constant()->get_value() );
    252                         int val;
     266                        int val = 0;
    253267                        std::string tmp;
    254268                        if ( ss >> val && ! (ss >> tmp) ) {
     
    272286        }
    273287
    274         Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
     288        Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
     289                PRINT(
     290                        std::cerr << std::endl << "converting ";
     291                        actualType->print( std::cerr, 8 );
     292                        std::cerr << std::endl << " to ";
     293                        formalType->print( std::cerr, 8 );
     294                        std::cerr << std::endl << "environment is: ";
     295                        env.print( std::cerr, 8 );
     296                        std::cerr << std::endl;
     297                )
     298                Cost convCost = conversionCost( actualType, formalType, indexer, env );
     299                PRINT(
     300                        std::cerr << std::endl << "cost is" << convCost << std::endl;
     301                )
     302                if ( convCost == Cost::infinity ) {
     303                        return convCost;
     304                }
     305                convCost.incPoly( polyCost( formalType, env, indexer ) + polyCost( actualType, env, indexer ) );
     306                return convCost;
     307        }
     308
     309        Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
     310                Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
     311                // if ( convCost != Cost::zero ) {
     312
     313                // xxx - temporary -- ignore poly cost, since this causes some polymorphic functions to be cast, which causes the specialize
     314                // pass to try to specialize them, which currently does not work. Once that is fixed, remove the next 3 lines and uncomment the
     315                // previous line.
     316                Cost tmpCost = convCost;
     317                tmpCost.incPoly( -tmpCost.get_polyCost() );
     318                if ( tmpCost != Cost::zero ) {
     319                        Type *newType = formalType->clone();
     320                        env.apply( newType );
     321                        actualExpr = new CastExpr( actualExpr, newType );
     322                        // xxx - SHOULD be able to resolve this cast, but at the moment pointers are not castable to zero_t, but are implicitly convertible. This is clearly
     323                        // inconsistent, once this is fixed it should be possible to resolve the cast.
     324                        // xxx - this isn't working, it appears because type1 (the formal type) is seen as widenable, but it shouldn't be, because this makes the conversion from DT* to DT* since commontype(zero_t, DT*) is DT*, rather than just nothing.
     325
     326                        // AlternativeFinder finder( indexer, env );
     327                        // finder.findWithAdjustment( actualExpr );
     328                        // assertf( finder.get_alternatives().size() > 0, "Somehow castable expression failed to find alternatives." );
     329                        // assertf( finder.get_alternatives().size() == 1, "Somehow got multiple alternatives for known cast expression." );
     330                        // Alternative & alt = finder.get_alternatives().front();
     331                        // delete actualExpr;
     332                        // actualExpr = alt.expr->clone();
     333                }
     334                return convCost;
     335        }
     336
     337        Cost computeApplicationConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    275338                ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
    276339                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    277340                FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
    278341
    279                 Cost convCost( 0, 0, 0 );
     342                Cost convCost = Cost::zero;
    280343                std::list< DeclarationWithType* >& formals = function->get_parameters();
    281344                std::list< DeclarationWithType* >::iterator formal = formals.begin();
     
    290353                                actualType->print( std::cerr, 8 );
    291354                        )
    292                         Cost actualCost;
    293355                        if ( formal == formals.end() ) {
    294356                                if ( function->get_isVarArgs() ) {
    295                                         convCost += Cost( 1, 0, 0 );
     357                                        convCost.incUnsafe();
     358                                        // convert reference-typed expressions to value-typed expressions
     359                                        referenceToRvalueConversion( *actualExpr );
    296360                                        continue;
    297361                                } else {
     
    305369                                std::cerr << std::endl << " to ";
    306370                                formalType->print( std::cerr, 8 );
     371                                std::cerr << std::endl << "environment is: ";
     372                                alt.env.print( std::cerr, 8 );
     373                                std::cerr << std::endl;
    307374                        )
    308                         Cost newCost = conversionCost( actualType, formalType, indexer, alt.env );
    309                         PRINT(
    310                                 std::cerr << std::endl << "cost is" << newCost << std::endl;
    311                         )
    312 
    313                         if ( newCost == Cost::infinity ) {
    314                                 return newCost;
    315                         }
    316                         convCost += newCost;
    317                         actualCost += newCost;
    318                         if ( actualCost != Cost( 0, 0, 0 ) ) {
    319                                 Type *newType = formalType->clone();
    320                                 alt.env.apply( newType );
    321                                 *actualExpr = new CastExpr( *actualExpr, newType );
    322                         }
    323                         convCost += Cost( 0, polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ), 0 );
     375                        convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env );
    324376                        ++formal; // can't be in for-loop update because of the continue
    325377                }
     
    329381
    330382                for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
    331                         PRINT(
    332                                 std::cerr << std::endl << "converting ";
    333                                 assert->second.actualType->print( std::cerr, 8 );
    334                                 std::cerr << std::endl << " to ";
    335                                 assert->second.formalType->print( std::cerr, 8 );
    336                         )
    337                         Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
    338                         PRINT(
    339                                 std::cerr << std::endl << "cost of conversion is " << newCost << std::endl;
    340                         )
    341                         if ( newCost == Cost::infinity ) {
    342                                 return newCost;
    343                         }
    344                         convCost += newCost;
    345                         convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ), 0 );
     383                        convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
    346384                }
    347385
     
    400438                        Expression * actual = actualIt->expr;
    401439                        Type * actualType = actual->get_result();
     440
    402441                        PRINT(
    403442                                std::cerr << "formal type is ";
     
    408447                        )
    409448                        if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     449                                // std::cerr << "unify failed" << std::endl;
    410450                                return false;
    411451                        }
     
    452492                        // match flattened actuals with formal parameters - actuals will be grouped to match
    453493                        // with formals as appropriate
    454                         Cost cost;
     494                        Cost cost = Cost::zero;
    455495                        std::list< Expression * > newExprs;
    456496                        ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal );
     
    613653                AssertionSet newNeed;
    614654                //AssertionParentSet needParents;
     655                PRINT(
     656                        std::cerr << "env is: " << std::endl;
     657                        newAlt.env.print( std::cerr, 0 );
     658                        std::cerr << std::endl;
     659                )
     660
    615661                inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out );
    616662//      PRINT(
     
    643689                        makeExprList( instantiatedActuals, appExpr->get_args() );
    644690                        PRINT(
     691                                std::cerr << "instantiate function success: " << appExpr << std::endl;
    645692                                std::cerr << "need assertions:" << std::endl;
    646693                                printAssertionSet( resultNeed, std::cerr, 8 );
     
    663710                                UntypedExpr *vexpr = untypedExpr->clone();
    664711                                vexpr->set_result( pt.clone() );
    665                                 alternatives.push_back( Alternative( vexpr, env, Cost()) );
     712                                alternatives.push_back( Alternative( vexpr, env, Cost::zero) );
    666713                                return;
    667714                        }
     
    681728                AltList candidates;
    682729                SemanticError errors;
    683                 for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
     730                for ( AltList::iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
    684731                        try {
    685732                                PRINT(
     
    688735                                )
    689736                                // check if the type is pointer to function
    690                                 PointerType *pointer;
    691                                 if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {
     737                                if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
    692738                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     739                                                referenceToRvalueConversion( func->expr );
    693740                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    694741                                                        // XXX
     
    696743                                                        makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    697744                                                }
    698                                         } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
    699                                                 EqvClass eqvClass;
    700                                                 if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
    701                                                         if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
    702                                                                 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    703                                                                         makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    704                                                                 } // for
    705                                                         } // if
     745                                        }
     746                                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
     747                                        referenceToRvalueConversion( func->expr );
     748                                        EqvClass eqvClass;
     749                                        if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
     750                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
     751                                                        for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     752                                                                makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     753                                                        } // for
    706754                                                } // if
    707755                                        } // if
     
    722770                                        }
    723771
    724                                         for ( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
     772                                        for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
    725773                                                // check if the type is pointer to function
    726                                                 PointerType *pointer;
    727                                                 if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) {
     774                                                if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) {
    728775                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
     776                                                                referenceToRvalueConversion( funcOp->expr );
    729777                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    730778                                                                        AltList currentAlt;
     
    747795                // compute conversionsion costs
    748796                for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
    749                         Cost cvtCost = computeConversionCost( *withFunc, indexer );
     797                        Cost cvtCost = computeApplicationConversionCost( *withFunc, indexer );
    750798
    751799                        PRINT(
     
    753801                                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    754802                                FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
    755                                 std::cerr << "Case +++++++++++++" << std::endl;
     803                                std::cerr << "Case +++++++++++++ " << appExpr->get_function() << std::endl;
    756804                                std::cerr << "formals are:" << std::endl;
    757805                                printAll( function->get_parameters(), std::cerr, 8 );
     
    796844        bool isLvalue( Expression *expr ) {
    797845                // xxx - recurse into tuples?
    798                 return expr->has_result() && expr->get_result()->get_lvalue();
     846                return expr->has_result() && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
    799847        }
    800848
     
    810858
    811859        Expression * restructureCast( Expression * argExpr, Type * toType ) {
    812                 if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) {
    813                         // Argument expression is a tuple and the target type is not void. Cast each member of the tuple
    814                         // to its corresponding target type, producing the tuple of those cast expressions. If there are
    815                         // more components of the tuple than components in the target type, then excess components do not
    816                         // come out in the result expression (but UniqueExprs ensure that side effects will still be done).
    817                         if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
     860                if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() && ! dynamic_cast<ReferenceType *>( toType ) ) {
     861                        // Argument expression is a tuple and the target type is not void and not a reference type.
     862                        // Cast each member of the tuple to its corresponding target type, producing the tuple of those
     863                        // cast expressions. If there are more components of the tuple than components in the target type,
     864                        // then excess components do not come out in the result expression (but UniqueExprs ensure that
     865                        // side effects will still be done).
     866                        if ( Tuples::maybeImpureIgnoreUnique( argExpr ) ) {
    818867                                // expressions which may contain side effects require a single unique instance of the expression.
    819868                                argExpr = new UniqueExpr( argExpr );
     
    855904                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    856905                        // to.
    857                         int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
     906                        int discardedValues = i->expr->get_result()->size() - castExpr->get_result()->size();
    858907                        if ( discardedValues < 0 ) continue;
    859908                        // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
    860909                        // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
    861910                        // unification run for side-effects
    862                         unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
    863                         Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env );
     911                        unify( castExpr->get_result(), i->expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
     912                        Cost thisCost = castCost( i->expr->get_result(), castExpr->get_result(), indexer, i->env );
    864913                        if ( thisCost != Cost::infinity ) {
    865914                                // count one safe conversion for each value that is thrown away
    866                                 thisCost += Cost( 0, 0, discardedValues );
    867 
    868                                 candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) );
     915                                thisCost.incSafe( discardedValues );
     916                                Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost );
     917                                // xxx - this doesn't work at the moment, since inferParameters requires an ApplicationExpr as the alternative.
     918                                // Once this works, it should be possible to infer parameters on a cast expression and specialize any function.
     919
     920                                // inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
     921                                candidates.emplace_back( std::move( newAlt ) );
    869922                        } // if
    870923                } // for
     
    895948                funcFinder.findWithAdjustment( memberExpr->get_aggregate() );
    896949                for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
    897                         if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) {
    898                                 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    899                         } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) {
    900                                 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    901                         } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( agg->expr->get_result() ) ) {
    902                                 addTupleMembers( tupleType, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
     950                        // 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
     951                        std::unique_ptr<Expression> aggrExpr( agg->expr->clone() );
     952                        Type * aggrType = aggrExpr->get_result();
     953                        if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
     954                                aggrType = aggrType->stripReferences();
     955                                aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );
     956                        }
     957                        // find member of the given type
     958                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
     959                                addAggMembers( structInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
     960                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
     961                                addAggMembers( unionInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
     962                        } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
     963                                addTupleMembers( tupleType, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
    903964                        } // if
    904965                } // for
     
    915976                for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
    916977                        VariableExpr newExpr( *i, nameExpr->get_argName() );
    917                         alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
     978                        alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
    918979                        PRINT(
    919980                                std::cerr << "decl is ";
     
    9551016                        // return the lowest cost alternative for the argument
    9561017                        Alternative &choice = winners.front();
     1018                        referenceToRvalueConversion( choice.expr );
    9571019                        alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
    9581020                } // if
     
    9751037                        // return the lowest cost alternative for the argument
    9761038                        Alternative &choice = winners.front();
     1039                        referenceToRvalueConversion( choice.expr );
    9771040                        alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
    9781041                } // if
     
    10591122                        for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
    10601123                                VariableExpr newExpr( *i );
    1061                                 alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
     1124                                alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
    10621125                                renameTypes( alternatives.back().expr );
    10631126                        } // for
     
    10991162                                                ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    11001163                                                newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
     1164                                                // convert both options to the conditional result type
     1165                                                newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env );
     1166                                                newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env );
    11011167                                                newAlt.expr = newExpr;
    11021168                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     
    12321298                                if ( thisCost != Cost::infinity ) {
    12331299                                        // count one safe conversion for each value that is thrown away
    1234                                         thisCost += Cost( 0, 0, discardedValues );
     1300                                        thisCost.incSafe( discardedValues );
    12351301                                        candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) );
    12361302                                }
Note: See TracChangeset for help on using the changeset viewer.