Changeset 11094d9 for src


Ignore:
Timestamp:
Nov 16, 2017, 12:25:56 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
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:
b7f8cb4
Parents:
0873968c
Message:

Fix duplicate anonymous member alternative generation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r0873968c r11094d9  
    581581                std::vector<unsigned> tupleEls;  /// Number of elements in current tuple element(s)
    582582
    583                 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 
     583                ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have,
    584584                                const OpenVarSet& openVars)
    585585                        : actuals(), env(env), need(need), have(have), openVars(openVars), nextArg(0),
    586586                          expls(), nextExpl(0), tupleEls() {}
    587                
     587
    588588                /// Starts a new tuple expression
    589589                void beginTuple() {
     
    620620
    621621        /// Instantiates an argument to match a formal, returns false if no results left
    622         bool instantiateArgument( Type* formalType, Initializer* initializer, 
    623                         const std::vector< AlternativeFinder >& args, 
    624                         std::vector<ArgPack>& results, std::vector<ArgPack>& nextResults, 
     622        bool instantiateArgument( Type* formalType, Initializer* initializer,
     623                        const std::vector< AlternativeFinder >& args,
     624                        std::vector<ArgPack>& results, std::vector<ArgPack>& nextResults,
    625625                        const SymTab::Indexer& indexer ) {
    626626                if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) {
     
    629629                        for ( Type* type : *tupleType ) {
    630630                                // xxx - dropping initializer changes behaviour from previous, but seems correct
    631                                 if ( ! instantiateArgument( type, nullptr, args, results, nextResults, indexer ) ) 
     631                                if ( ! instantiateArgument( type, nullptr, args, results, nextResults, indexer ) )
    632632                                        return false;
    633633                        }
     
    658658                                                Type* argType = result.actuals.back().expr->get_result();
    659659                                                if ( result.tupleEls.back() == 1 && Tuples::isTtype( argType ) ) {
    660                                                         // the case where a ttype value is passed directly is special, e.g. for 
     660                                                        // the case where a ttype value is passed directly is special, e.g. for
    661661                                                        // argument forwarding purposes
    662662                                                        // xxx - what if passing multiple arguments, last of which is ttype?
    663                                                         // xxx - what would happen if unify was changed so that unifying tuple 
     663                                                        // xxx - what would happen if unify was changed so that unifying tuple
    664664                                                        // types flattened both before unifying lists? then pass in TupleType
    665665                                                        // (ttype) below.
     
    671671                                                }
    672672                                                // check unification for ttype before adding to final
    673                                                 if ( unify( ttype, argType, result.env, result.need, result.have, 
     673                                                if ( unify( ttype, argType, result.env, result.need, result.have,
    674674                                                                result.openVars, indexer ) ) {
    675675                                                        finalResults.push_back( std::move(result) );
     
    684684                                                aResult.env.addActual( actual.env, aResult.openVars );
    685685                                                Cost cost = actual.cost;
    686                
     686
    687687                                                // explode argument
    688688                                                std::vector<Alternative> exploded;
    689689                                                Tuples::explode( actual, indexer, back_inserter( exploded ) );
    690                                                
     690
    691691                                                // add exploded argument to tuple
    692692                                                for ( Alternative& aActual : exploded ) {
     
    706706                        return ! results.empty();
    707707                }
    708                
     708
    709709                // iterate each current subresult
    710710                for ( unsigned iResult = 0; iResult < results.size(); ++iResult ) {
     
    724724                                        std::cerr << std::endl;
    725725                                )
    726                                
    727                                 if ( unify( formalType, actualType, result.env, result.need, result.have, 
     726
     727                                if ( unify( formalType, actualType, result.env, result.need, result.have,
    728728                                                result.openVars, indexer ) ) {
    729729                                        ++result.nextExpl;
     
    736736                                if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) {
    737737                                        if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) {
    738                                                 if ( unify( formalType, cnst->get_type(), result.env, result.need, 
     738                                                if ( unify( formalType, cnst->get_type(), result.env, result.need,
    739739                                                                result.have, result.openVars, indexer ) ) {
    740740                                                        nextResults.push_back( std::move(result.withArg( cnstExpr )) );
     
    791791                results.swap( nextResults );
    792792                nextResults.clear();
    793                
     793
    794794                return ! results.empty();
    795         }       
     795        }
    796796
    797797        template<typename OutputIterator>
    798         void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, 
    799                         FunctionType *funcType, const std::vector< AlternativeFinder > &args, 
     798        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func,
     799                        FunctionType *funcType, const std::vector< AlternativeFinder > &args,
    800800                        OutputIterator out ) {
    801801                OpenVarSet funcOpenVars;
     
    803803                TypeEnvironment funcEnv( func.env );
    804804                makeUnifiableVars( funcType, funcOpenVars, funcNeed );
    805                 // add all type variables as open variables now so that those not used in the parameter 
     805                // add all type variables as open variables now so that those not used in the parameter
    806806                // list are still considered open.
    807807                funcEnv.add( funcType->get_forall() );
    808                
     808
    809809                if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) {
    810810                        // attempt to narrow based on expected target type
    811811                        Type * returnType = funcType->get_returnVals().front()->get_type();
    812                         if ( ! unify( returnType, targetType, funcEnv, funcNeed, funcHave, funcOpenVars, 
     812                        if ( ! unify( returnType, targetType, funcEnv, funcNeed, funcHave, funcOpenVars,
    813813                                        indexer ) ) {
    814814                                // unification failed, don't pursue this function alternative
     
    822822                for ( DeclarationWithType* formal : funcType->get_parameters() ) {
    823823                        ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal );
    824                         if ( ! instantiateArgument( 
     824                        if ( ! instantiateArgument(
    825825                                        obj->get_type(), obj->get_init(), args, results, nextResults, indexer ) )
    826826                                return;
     
    904904
    905905                std::vector< AlternativeFinder > argAlternatives;
    906                 findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), 
     906                findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(),
    907907                        back_inserter( argAlternatives ) );
    908908
     
    934934                                                Alternative newFunc( *func );
    935935                                                referenceToRvalueConversion( newFunc.expr );
    936                                                 makeFunctionAlternatives( newFunc, function, argAlternatives, 
     936                                                makeFunctionAlternatives( newFunc, function, argAlternatives,
    937937                                                        std::back_inserter( candidates ) );
    938938                                        }
     
    943943                                                        Alternative newFunc( *func );
    944944                                                        referenceToRvalueConversion( newFunc.expr );
    945                                                         makeFunctionAlternatives( newFunc, function, argAlternatives, 
     945                                                        makeFunctionAlternatives( newFunc, function, argAlternatives,
    946946                                                                std::back_inserter( candidates ) );
    947947                                                } // if
    948948                                        } // if
    949                                 }                       
     949                                }
    950950                        } catch ( SemanticError &e ) {
    951951                                errors.append( e );
     
    962962                                try {
    963963                                        // check if type is a pointer to function
    964                                         if ( PointerType* pointer = dynamic_cast<PointerType*>( 
     964                                        if ( PointerType* pointer = dynamic_cast<PointerType*>(
    965965                                                        funcOp->expr->get_result()->stripReferences() ) ) {
    966                                                 if ( FunctionType* function = 
     966                                                if ( FunctionType* function =
    967967                                                                dynamic_cast<FunctionType*>( pointer->get_base() ) ) {
    968968                                                        Alternative newFunc( *funcOp );
    969969                                                        referenceToRvalueConversion( newFunc.expr );
    970                                                         makeFunctionAlternatives( newFunc, function, argAlternatives, 
     970                                                        makeFunctionAlternatives( newFunc, function, argAlternatives,
    971971                                                                std::back_inserter( candidates ) );
    972972                                                }
     
    10071007                candidates.splice( candidates.end(), alternatives );
    10081008
    1009                 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) );
     1009                // use a new list so that alternatives are not examined by addAnonConversions twice.
     1010                AltList winners;
     1011                findMinCost( candidates.begin(), candidates.end(), std::back_inserter( winners ) );
    10101012
    10111013                // function may return struct or union value, in which case we need to add alternatives for implicit
    10121014                // conversions to each of the anonymous members, must happen after findMinCost since anon conversions
    10131015                // are never the cheapest expression
    1014                 for ( const Alternative & alt : alternatives ) {
     1016                for ( const Alternative & alt : winners ) {
    10151017                        addAnonConversions( alt );
    10161018                }
     1019                alternatives.splice( alternatives.begin(), winners );
    10171020
    10181021                if ( alternatives.empty() && targetType && ! targetType->isVoid() ) {
Note: See TracChangeset for help on using the changeset viewer.