Changes in / [5b643ea:cef5bfc]


Ignore:
Files:
6 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/GenPoly.cpp

    r5b643ea rcef5bfc  
    2727#include "AST/Type.hpp"
    2828#include "AST/TypeSubstitution.hpp"
    29 #include "Common/Eval.hpp"                // for eval
    3029#include "GenPoly/ErasableScopedMap.hpp"  // for ErasableScopedMap<>::const_...
    3130#include "ResolvExpr/Typeops.hpp"         // for flatten
     
    244243} // namespace
    245244
    246 // This function, and its helpers following, have logic duplicated from
    247 // unification.  The difference in context is that unification applies where
    248 // the types "must" match, while this variation applies to arbitrary type
    249 // pairs, when an optimization could apply if they happen to match.  This
    250 // variation does not bind type variables.  The helper functions support
    251 // the case for matching ArrayType.
    252 bool typesPolyCompatible( ast::Type const * lhs, ast::Type const * rhs );
    253 
    254 static bool exprsPolyCompatibleByStaticValue(
    255                 const ast::Expr * e1, const ast::Expr * e2 ) {
    256         Evaluation r1 = eval(e1);
    257         Evaluation r2 = eval(e2);
    258 
    259         if ( !r1.hasKnownValue ) return false;
    260         if ( !r2.hasKnownValue ) return false;
    261 
    262         if ( r1.knownValue != r2.knownValue ) return false;
    263 
    264         return true;
    265 }
    266 
    267 static bool exprsPolyCompatible( ast::Expr const * lhs,
    268                 ast::Expr const * rhs ) {
    269         type_index const lid = typeid(*lhs);
    270         type_index const rid = typeid(*rhs);
    271         if ( lid != rid ) return false;
    272 
    273         if ( exprsPolyCompatibleByStaticValue( lhs, rhs ) ) return true;
    274 
    275         if ( type_index(typeid(ast::CastExpr)) == lid ) {
    276                 ast::CastExpr const * l = as<ast::CastExpr>(lhs);
    277                 ast::CastExpr const * r = as<ast::CastExpr>(rhs);
    278 
    279                 // inspect casts' target types
    280                 if ( !typesPolyCompatible(
    281                         l->result, r->result ) ) return false;
    282 
    283                 // inspect casts' inner expressions
    284                 return exprsPolyCompatible( l->arg, r->arg );
    285 
    286         } else if ( type_index(typeid(ast::VariableExpr)) == lid ) {
    287                 ast::VariableExpr const * l = as<ast::VariableExpr>(lhs);
    288                 ast::VariableExpr const * r = as<ast::VariableExpr>(rhs);
    289 
    290                 assert(l->var);
    291                 assert(r->var);
    292 
    293                 // conservative: variable exprs match if their declarations are
    294                 // represented by the same C++ AST object
    295                 return (l->var == r->var);
    296 
    297         } else if ( type_index(typeid(ast::SizeofExpr)) == lid ) {
    298                 ast::SizeofExpr const * l = as<ast::SizeofExpr>(lhs);
    299                 ast::SizeofExpr const * r = as<ast::SizeofExpr>(rhs);
    300 
    301                 assert((l->type != nullptr) ^ (l->expr != nullptr));
    302                 assert((r->type != nullptr) ^ (r->expr != nullptr));
    303                 if ( !(l->type && r->type) ) return false;
    304 
    305                 // mutual recursion with type poly compatibility
    306                 return typesPolyCompatible( l->type, r->type );
    307 
    308         } else {
    309                 // All other forms compare on static value only, done earlier
    310                 return false;
    311         }
    312 }
    313 
    314245bool typesPolyCompatible( ast::Type const * lhs, ast::Type const * rhs ) {
    315246        type_index const lid = typeid(*lhs);
     
    325256
    326257        // So remaining types can be examined case by case.
    327         // Recurse through type structure (conditions duplicated from Unify.cpp).
     258        // Recurse through type structure (conditions borrowed from Unify.cpp).
    328259
    329260        if ( type_index(typeid(ast::BasicType)) == lid ) {
     
    349280                ast::ArrayType const * r = as<ast::ArrayType>(rhs);
    350281
    351                 if ( l->isVarLen != r->isVarLen ) return false;
    352                 if ( (l->dimension != nullptr) != (r->dimension != nullptr) )
    353                         return false;
    354 
    355                 if ( l->dimension ) {
    356                         assert( r->dimension );
    357                         // mutual recursion with expression poly compatibility
    358                         if ( !exprsPolyCompatible(l->dimension, r->dimension) )
     282                if ( l->isVarLen ) {
     283                        if ( !r->isVarLen ) return false;
     284                } else {
     285                        if ( r->isVarLen ) return false;
     286
     287                        auto lc = l->dimension.as<ast::ConstantExpr>();
     288                        auto rc = r->dimension.as<ast::ConstantExpr>();
     289                        if ( lc && rc && lc->intValue() != rc->intValue() ) {
    359290                                return false;
     291                        }
    360292                }
    361293
  • src/ResolvExpr/CandidateFinder.cpp

    r5b643ea rcef5bfc  
    12411241                Cost minCastCost = Cost::infinity;
    12421242                for ( CandidateRef & cand : finder.candidates ) {
    1243                         ast::ptr< ast::Type > fromType = cand->expr->result;
    1244                         assert( fromType );
    1245                         fromType = resolveTypeof( fromType, context );
    1246                         fromType = adjustExprType( fromType, tenv, symtab );
    1247 
    12481243                        ast::AssertionSet need( cand->need.begin(), cand->need.end() ), have;
    12491244                        ast::OpenVarSet open( cand->open );
     
    12551250                        // subexpression results that are cast directly. The candidate is invalid if it
    12561251                        // has fewer results than there are types to cast to.
    1257                         int discardedValues = fromType->size() - toType->size();
     1252                        int discardedValues = cand->expr->result->size() - toType->size();
    12581253                        if ( discardedValues < 0 ) continue;
    12591254
    12601255                        // unification run for side-effects
    1261                         unify( toType, fromType, cand->env, need, have, open );
     1256                        unify( toType, cand->expr->result, cand->env, need, have, open );
    12621257                        Cost thisCost =
    12631258                                (castExpr->isGenerated == ast::GeneratedFlag::GeneratedCast)
    1264                                         ? conversionCost( fromType, toType, cand->expr->get_lvalue(), symtab, cand->env )
    1265                                         : castCost( fromType, toType, cand->expr->get_lvalue(), symtab, cand->env );
     1259                                        ? conversionCost( cand->expr->result, toType, cand->expr->get_lvalue(), symtab, cand->env )
     1260                                        : castCost( cand->expr->result, toType, cand->expr->get_lvalue(), symtab, cand->env );
    12661261                       
    12671262                        // Redefine enum cast
    1268                         auto argAsEnum = fromType.as<ast::EnumInstType>();
     1263                        auto argAsEnum = cand->expr->result.as<ast::EnumInstType>();
    12691264                        auto toAsEnum = toType.as<ast::EnumInstType>();
    12701265                        if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {
     
    12771272                        PRINT(
    12781273                                std::cerr << "working on cast with result: " << toType << std::endl;
    1279                                 std::cerr << "and expr type: " << fromType << std::endl;
     1274                                std::cerr << "and expr type: " << cand->expr->result << std::endl;
    12801275                                std::cerr << "env: " << cand->env << std::endl;
    12811276                        )
     
    12861281                                // count one safe conversion for each value that is thrown away
    12871282                                thisCost.incSafe( discardedValues );
    1288 
    1289                                 // See Aaron Moss, page 47; this reasoning does not hold since implicit conversions
    1290                                 // can create the same resolution issue. The C intrinsic interpretations are pruned
    1291                                 // immediately for the lowest cost option regardless of result type. Related code in
    1292                                 // postvisit (UntypedExpr).
    1293                                 // Cast expression costs are updated now to use the general rules.
    1294                                 /*
    12951283                                // select first on argument cost, then conversion cost
    12961284                                if ( cand->cost < minExprCost || ( cand->cost == minExprCost && thisCost < minCastCost ) ) {
     
    13011289                                // ambigious case, still output candidates to print in error message
    13021290                                if ( cand->cost == minExprCost && thisCost == minCastCost ) {
    1303                                 */
    1304                                 cand->cost += thisCost;
    1305                                 if (cand->cost < minExprCost) {
    1306                                         minExprCost = cand->cost;
    1307                                         matches.clear();
    1308                                 }
    1309                                 if (cand->cost == minExprCost) {
    13101291                                        CandidateRef newCand = std::make_shared<Candidate>(
    13111292                                                restructureCast( cand->expr, toType, castExpr->isGenerated ),
    1312                                                 copy( cand->env ), std::move( open ), std::move( need ), cand->cost);
     1293                                                copy( cand->env ), std::move( open ), std::move( need ), cand->cost + thisCost);
    13131294                                        // currently assertions are always resolved immediately so this should have no effect.
    13141295                                        // if this somehow changes in the future (e.g. delayed by indeterminate return type)
  • tests/array-collections/dimexpr-match.hfa

    r5b643ea rcef5bfc  
    1515//
    1616//      compiler=gcc -x c           # pick one
    17 //      compiler=$cfa
     17//      compiler=$fa
    1818//
    1919//      test=dimexpr-match-c.cfa    # pick one
Note: See TracChangeset for help on using the changeset viewer.