Changeset 4f748c5 for src/ResolvExpr


Ignore:
Timestamp:
Nov 2, 2017, 11:45:10 AM (8 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:
6de43b6
Parents:
b1e68d03 (diff), fde89cf6 (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 'fix-missing-cast-warning'

Location:
src/ResolvExpr
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rb1e68d03 r4f748c5  
    122122                                                )
    123123                                                mapPlace->second.isAmbiguous = true;
     124                                        } else {
     125                                                PRINT(
     126                                                        std::cerr << "cost " << candidate->cost << " loses to " << mapPlace->second.candidate->cost << std::endl;
     127                                                )
    124128                                        }
    125129                                } else {
     
    127131                                }
    128132                        }
    129 
    130                         PRINT(
    131                                 std::cerr << "there are " << selected.size() << " alternatives before elimination" << std::endl;
    132                         )
    133133
    134134                        // accept the alternatives that were unambiguous
     
    181181                }
    182182                if ( prune ) {
     183                        auto oldsize = alternatives.size();
    183184                        PRINT(
    184185                                std::cerr << "alternatives before prune:" << std::endl;
     
    198199                        }
    199200                        alternatives.erase( oldBegin, alternatives.end() );
     201                        PRINT(
     202                                std::cerr << "there are " << oldsize << " alternatives before elimination" << std::endl;
     203                        )
    200204                        PRINT(
    201205                                std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
     
    319323        Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
    320324                Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
    321                 // if ( convCost != Cost::zero ) {
    322 
    323                 // xxx - temporary -- ignore poly cost, since this causes some polymorphic functions to be cast, which causes the specialize
    324                 // pass to try to specialize them, which currently does not work. Once that is fixed, remove the next 3 lines and uncomment the
    325                 // previous line.
     325
     326                // if there is a non-zero conversion cost, ignoring poly cost, then the expression requires conversion.
     327                // ignore poly cost for now, since this requires resolution of the cast to infer parameters and this
     328                // does not currently work for the reason stated below.
    326329                Cost tmpCost = convCost;
    327330                tmpCost.incPoly( -tmpCost.get_polyCost() );
    328331                if ( tmpCost != Cost::zero ) {
     332                // if ( convCost != Cost::zero ) {
    329333                        Type *newType = formalType->clone();
    330334                        env.apply( newType );
     
    632636                                        std::cerr << std::endl;
    633637                                )
    634                                 ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );
    635638                                // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter).
    636                                 InferredParams * inferParameters = &appExpr->get_inferParams();
     639                                InferredParams * inferParameters = &newerAlt.expr->get_inferParams();
    637640                                for ( UniqueId id : cur->second.idChain ) {
    638641                                        inferParameters = (*inferParameters)[ id ].inferParams.get();
     
    681684                OpenVarSet openVars;
    682685                AssertionSet resultNeed, resultHave;
    683                 TypeEnvironment resultEnv;
     686                TypeEnvironment resultEnv( func.env );
    684687                makeUnifiableVars( funcType, openVars, resultNeed );
    685688                resultEnv.add( funcType->get_forall() ); // add all type variables as open variables now so that those not used in the parameter list are still considered open
     
    915918                                thisCost.incSafe( discardedValues );
    916919                                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 ) );
     920                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    922921                        } // if
    923922                } // for
     
    12981297                                        // count one safe conversion for each value that is thrown away
    12991298                                        thisCost.incSafe( discardedValues );
    1300                                         candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) );
     1299                                        Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost );
     1300                                        inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    13011301                                }
    13021302                        }
  • src/ResolvExpr/ConversionCost.cc

    rb1e68d03 r4f748c5  
    2828
    2929namespace ResolvExpr {
    30         const Cost Cost::zero = Cost( 0, 0, 0, 0 );
    31         const Cost Cost::infinity = Cost( -1, -1, -1, -1 );
    32         const Cost Cost::unsafe = Cost( 1, 0, 0, 0 );
    33         const Cost Cost::poly = Cost( 0, 1, 0, 0 );
    34         const Cost Cost::safe = Cost( 0, 0, 1, 0 );
    35         const Cost Cost::reference = Cost( 0, 0, 0, 1 );
     30        const Cost Cost::zero =      Cost(  0,  0,  0, 0 );
     31        const Cost Cost::infinity =  Cost( -1, -1, -1, -1 );
     32        const Cost Cost::unsafe =    Cost(  1,  0,  0, 0 );
     33        const Cost Cost::poly =      Cost(  0,  1,  0, 0 );
     34        const Cost Cost::safe =      Cost(  0,  0,  1, 0 );
     35        const Cost Cost::reference = Cost(  0,  0,  0, 1 );
    3636
    3737#if 0
     
    113113                                        int assignResult = func( srcAsRef->get_base(), destAsRef->get_base(), env, indexer );
    114114                                        PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
    115                                         if ( assignResult < 0 ) {
     115                                        if ( assignResult > 0 ) {
    116116                                                return Cost::safe;
    117                                         } else if ( assignResult > 0 ) {
     117                                        } else if ( assignResult < 0 ) {
    118118                                                return Cost::unsafe;
    119119                                        } // if
     
    269269        }
    270270
    271         void ConversionCost::visit(PointerType *pointerType) {
     271        void ConversionCost::visit( PointerType * pointerType ) {
    272272                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    273273                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr; )
     
    284284                                }
    285285                        } else {  // xxx - this discards qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    286                                 int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env );
     286                                int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
    287287                                PRINT( std::cerr << " :: " << assignResult << std::endl; )
    288                                 if ( assignResult < 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) {
     288                                if ( assignResult > 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) {
    289289                                        cost = Cost::safe;
    290                                 } else if ( assignResult > 0 ) {
     290                                } else if ( assignResult < 0 ) {
    291291                                        cost = Cost::unsafe;
    292292                                } // if
    293293                                // assignResult == 0 means Cost::Infinity
    294294                        } // if
    295                 } else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) {
     295                } else if ( dynamic_cast< ZeroType * >( dest ) ) {
    296296                        cost = Cost::unsafe;
    297297                } // if
    298298        }
    299299
    300         void ConversionCost::visit(__attribute((unused)) ArrayType *arrayType) {}
    301 
    302         void ConversionCost::visit(ReferenceType *refType) {
     300        void ConversionCost::visit( ArrayType * ) {}
     301
     302        void ConversionCost::visit( ReferenceType * refType ) {
    303303                // Note: dest can never be a reference, since it would have been caught in an earlier check
    304304                assert( ! dynamic_cast< ReferenceType * >( dest ) );
     
    317317        }
    318318
    319         void ConversionCost::visit(__attribute((unused)) FunctionType *functionType) {}
    320 
    321         void ConversionCost::visit(StructInstType *inst) {
     319        void ConversionCost::visit( FunctionType * ) {}
     320
     321        void ConversionCost::visit( StructInstType * inst ) {
    322322                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    323323                        if ( inst->name == destAsInst->name ) {
     
    327327        }
    328328
    329         void ConversionCost::visit(UnionInstType *inst) {
     329        void ConversionCost::visit( UnionInstType * inst ) {
    330330                if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
    331331                        if ( inst->name == destAsInst->name ) {
     
    335335        }
    336336
    337         void ConversionCost::visit( __attribute((unused)) EnumInstType *inst ) {
     337        void ConversionCost::visit( EnumInstType * ) {
    338338                static Type::Qualifiers q;
    339339                static BasicType integer( q, BasicType::SignedInt );
     
    344344        }
    345345
    346         void ConversionCost::visit( __attribute((unused)) TraitInstType *inst) {
    347         }
    348 
    349         void ConversionCost::visit(TypeInstType *inst) {
     346        void ConversionCost::visit( TraitInstType * ) {}
     347
     348        void ConversionCost::visit( TypeInstType *inst ) {
    350349                EqvClass eqvClass;
    351350                NamedTypeDecl *namedType;
     
    366365        }
    367366
    368         void ConversionCost::visit( __attribute((unused)) TupleType *tupleType) {
     367        void ConversionCost::visit( TupleType * tupleType ) {
    369368                Cost c = Cost::zero;
    370                 if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {
    371                         std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
    372                         std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
     369                if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
     370                        std::list< Type * >::const_iterator srcIt = tupleType->get_types().begin();
     371                        std::list< Type * >::const_iterator destIt = destAsTuple->get_types().begin();
    373372                        while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
    374373                                Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
     
    386385        }
    387386
    388         void ConversionCost::visit( __attribute((unused)) VarArgsType *varArgsType) {
     387        void ConversionCost::visit( VarArgsType * ) {
    389388                if ( dynamic_cast< VarArgsType* >( dest ) ) {
    390389                        cost = Cost::zero;
     
    392391        }
    393392
    394         void ConversionCost::visit( __attribute((unused)) ZeroType *zeroType) {
    395                 if ( dynamic_cast< ZeroType* >( dest ) ) {
     393        void ConversionCost::visit( ZeroType * ) {
     394                if ( dynamic_cast< ZeroType * >( dest ) ) {
    396395                        cost = Cost::zero;
    397396                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     
    409408        }
    410409
    411         void ConversionCost::visit( __attribute((unused)) OneType *oneType) {
    412                 if ( dynamic_cast< OneType* >( dest ) ) {
     410        void ConversionCost::visit( OneType * ) {
     411                if ( dynamic_cast< OneType * >( dest ) ) {
    413412                        cost = Cost::zero;
    414413                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
  • src/ResolvExpr/PolyCost.cc

    rb1e68d03 r4f748c5  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // PolyCost.cc -- 
     7// PolyCost.cc --
    88//
    99// Author           : Richard C. Bilson
     
    3131        };
    3232
    33         int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     33        int polyCost( Type *type, const TypeEnvironment & env, const SymTab::Indexer &indexer ) {
    3434                PolyCost coster( env, indexer );
    3535                type->accept( coster );
     
    3737        }
    3838
    39         PolyCost::PolyCost( const TypeEnvironment &env, const SymTab::Indexer &indexer ) : result( 0 ), env( env ), indexer( indexer ) {
     39        PolyCost::PolyCost( const TypeEnvironment & env, const SymTab::Indexer & indexer ) : result( 0 ), env( env ), indexer( indexer ) {
    4040        }
    4141
    42         void PolyCost::visit(TypeInstType *typeInst) {
     42        void PolyCost::visit(TypeInstType * typeInst) {
    4343                EqvClass eqvClass;
    44                 if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     44                if ( env.lookup( typeInst->name, eqvClass ) ) {
    4545                        if ( eqvClass.type ) {
    46                                 if ( TypeInstType *otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
    47                                         if ( indexer.lookupType( otherTypeInst->get_name() ) ) {
     46                                if ( TypeInstType * otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
     47                                        if ( indexer.lookupType( otherTypeInst->name ) ) {
     48                                                // bound to opaque type
    4849                                                result += 1;
    4950                                        } // if
    5051                                } else {
     52                                        // bound to concrete type
    5153                                        result += 1;
    5254                                } // if
  • src/ResolvExpr/PtrsAssignable.cc

    rb1e68d03 r4f748c5  
    4747
    4848        int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {
     49                // std::cerr << "assignable: " << src << " | " << dest << std::endl;
    4950                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    5051                        EqvClass eqvClass;
     
    5455                } // if
    5556                if ( dynamic_cast< VoidType* >( dest ) ) {
    56                         return 1;
     57                        // void * = T * for any T is unsafe
     58                        // xxx - this should be safe, but that currently breaks the build
     59                        return -1;
    5760                } else {
    5861                        PtrsAssignable ptrs( dest, env );
     
    6568
    6669        void PtrsAssignable::visit( __attribute((unused)) VoidType *voidType ) {
    67                 if ( dynamic_cast< FunctionType* >( dest ) ) {
    68                         result = 0;
    69                 } else {
    70                         result = -1;
     70                if ( ! dynamic_cast< FunctionType* >( dest ) ) {
     71                        // T * = void * is safe for any T that is not a function type.
     72                        // xxx - this should be unsafe...
     73                        result = 1;
    7174                } // if
    7275        }
     
    7578        void PtrsAssignable::visit( __attribute__((unused)) PointerType *pointerType ) {}
    7679        void PtrsAssignable::visit( __attribute__((unused)) ArrayType *arrayType ) {}
    77         void PtrsAssignable::visit( __attribute__((unused)) FunctionType *functionType ) {
    78                 result = -1;
    79         }
     80        void PtrsAssignable::visit( __attribute__((unused)) FunctionType *functionType ) {}
    8081
    8182        void PtrsAssignable::visit(  __attribute__((unused)) StructInstType *inst ) {}
     
    8384
    8485        void PtrsAssignable::visit( EnumInstType * ) {
    85                 if ( dynamic_cast< EnumInstType* >( dest ) ) {
     86                if ( dynamic_cast< BasicType* >( dest ) ) {
     87                        // int * = E *, etc. is safe. This isn't technically correct, as each
     88                        // enum has one basic type that it is compatible with, an that type can
     89                        // differ from enum to enum. Without replicating GCC's internal logic,
     90                        // there is no way to know which type this particular enum is compatible
     91                        // with, so punt on this for now.
    8692                        result = 1;
    87                 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {
    88                         result = bt->get_kind() == BasicType::SignedInt;
    8993                }
    9094        }
     
    9498                EqvClass eqvClass;
    9599                if ( env.lookup( inst->get_name(), eqvClass ) && eqvClass.type ) {
     100                        // T * = S * for any S depends on the type bound to T
    96101                        result = ptrsAssignable( eqvClass.type, dest, env );
    97                 } else {
    98                         result = 0;
    99102                } // if
    100103        }
  • src/ResolvExpr/PtrsCastable.cc

    rb1e68d03 r4f748c5  
    5050        };
    5151
    52         int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    53                 if ( dynamic_cast< FunctionType* >( src ) ) {
    54                         return -1;
    55                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
    56                         EqvClass eqvClass;
    57                         if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
    58                                 if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
    59                                         if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
     52        namespace {
     53                int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     54                        if ( dynamic_cast< FunctionType* >( src ) ) {
     55                                return -1;
     56                        } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
     57                                EqvClass eqvClass;
     58                                if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
     59                                        if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
     60                                                if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
     61                                                        return -1;
     62                                                } // if
     63                                        } //if
     64                                } else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     65                                        if ( eqvClass.data.kind == TypeDecl::Ftype ) {
    6066                                                return -1;
    6167                                        } // if
    62                                 } //if
    63                         } else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
    64                                 if ( eqvClass.data.kind == TypeDecl::Ftype ) {
    65                                         return -1;
    6668                                } // if
    67                         } // if
    68                 } //if
    69                 return 1;
    70         }
    71         int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    72                 return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
     69                        } //if
     70                        return 1;
     71                }
     72                int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     73                        return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
     74                }
    7375        }
    7476
     
    9395        }
    9496
    95         void PtrsCastable::visit( __attribute__((unused)) VoidType *voidType) {
     97        void PtrsCastable::visit( VoidType * ) {
    9698                result = objectCast( dest, env, indexer );
    9799        }
    98100
    99         void PtrsCastable::visit( __attribute__((unused)) BasicType *basicType) {
     101        void PtrsCastable::visit( BasicType * ) {
    100102                result = objectCast( dest, env, indexer );
    101103        }
    102104
    103         void PtrsCastable::visit( __attribute__((unused)) PointerType *pointerType) {
     105        void PtrsCastable::visit( PointerType * ) {
    104106                result = objectCast( dest, env, indexer );
    105107        }
    106108
    107         void PtrsCastable::visit( __attribute__((unused)) ArrayType *arrayType) {
     109        void PtrsCastable::visit( ArrayType * ) {
    108110                result = objectCast( dest, env, indexer );
    109111        }
    110112
    111         void PtrsCastable::visit( __attribute__((unused)) FunctionType *functionType) {
     113        void PtrsCastable::visit( FunctionType * ) {
    112114                // result = -1;
    113115                result = functionCast( dest, env, indexer );
    114116        }
    115117
    116         void PtrsCastable::visit( __attribute__((unused)) StructInstType *inst) {
     118        void PtrsCastable::visit( StructInstType * ) {
    117119                result = objectCast( dest, env, indexer );
    118120        }
    119121
    120         void PtrsCastable::visit( __attribute__((unused)) UnionInstType *inst) {
     122        void PtrsCastable::visit( UnionInstType * ) {
    121123                result = objectCast( dest, env, indexer );
    122124        }
    123125
    124         void PtrsCastable::visit( __attribute__((unused)) EnumInstType *inst) {
     126        void PtrsCastable::visit( EnumInstType * ) {
    125127                if ( dynamic_cast< EnumInstType* >( dest ) ) {
    126128                        result = 1;
     
    136138        }
    137139
    138         void PtrsCastable::visit( __attribute__((unused)) TraitInstType *inst ) {}
     140        void PtrsCastable::visit( TraitInstType * ) {}
    139141
    140142        void PtrsCastable::visit(TypeInstType *inst) {
     
    143145        }
    144146
    145         void PtrsCastable::visit( __attribute__((unused)) TupleType *tupleType) {
     147        void PtrsCastable::visit( TupleType * ) {
    146148                result = objectCast( dest, env, indexer );
    147149        }
    148150
    149         void PtrsCastable::visit( __attribute__((unused)) VarArgsType *varArgsType) {
     151        void PtrsCastable::visit( VarArgsType * ) {
    150152                result = objectCast( dest, env, indexer );
    151153        }
    152154
    153         void PtrsCastable::visit( __attribute__((unused)) ZeroType *zeroType) {
     155        void PtrsCastable::visit( ZeroType * ) {
    154156                result = objectCast( dest, env, indexer );
    155157        }
    156158
    157         void PtrsCastable::visit( __attribute__((unused)) OneType *oneType) {
     159        void PtrsCastable::visit( OneType * ) {
    158160                result = objectCast( dest, env, indexer );
    159161        }
  • src/ResolvExpr/Resolver.cc

    rb1e68d03 r4f748c5  
    593593                initExpr->expr = nullptr;
    594594                std::swap( initExpr->env, newExpr->env );
     595                std::swap( initExpr->inferParams, newExpr->inferParams ) ;
    595596                delete initExpr;
    596597
  • src/ResolvExpr/Unify.cc

    rb1e68d03 r4f748c5  
    138138        bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) {
    139139                switch ( data.kind ) {
    140                   case TypeDecl::Any:
    141140                  case TypeDecl::Dtype:
    142141                        // to bind to an object type variable, the type must not be a function type.
Note: See TracChangeset for help on using the changeset viewer.