Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Lvalue.cpp

    rb6f2e7ab rbdf40650  
    8585struct ReferenceConversions final :
    8686                public ast::WithConstTranslationUnit,
    87                 public ast::WithGuards, public ast::WithStmtsToAdd<> {
     87                public ast::WithGuards, public ast::WithStmtsToAdd {
    8888        ast::Expr const * postvisit( ast::CastExpr const * expr );
    8989        ast::Expr const * postvisit( ast::AddressExpr const * expr );
     
    316316                        Warning::RvalueToReferenceConversion, toCString( expr->arg ) );
    317317
     318                // allowing conversion in the rvalue to const ref case
     319                // use the referenced-to type to create temp variables
     320                ast::Type const * targetType = dstType;
     321                for (int i = 0; i < diff; ++i) targetType = (strict_dynamic_cast<ast::ReferenceType const *>(targetType))->base;
     322
    318323                static UniqueName tmpNamer( "__ref_tmp_" );
    319324                ast::ObjectDecl * tmp = new ast::ObjectDecl( expr->arg->location,
    320325                        tmpNamer.newName(),
    321                         ast::deepCopy( expr->arg->result ),
     326                        // ast::deepCopy( expr->arg->result ),
     327                        ast::deepCopy (targetType),
    322328                        new ast::SingleInit( expr->arg->location, expr->arg ) );
    323329                PRINT( std::cerr << "make tmp: " << tmp << std::endl; )
     
    359365                        ret = new ast::AddressExpr( ret->location, ret );
    360366                }
    361                 if ( expr->arg->get_lvalue() &&
    362                                 !ResolvExpr::typesCompatible(
    363                                         srcType,
    364                                         strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) {
    365                         // Must keep cast if cast-to type is different from the actual type.
     367                // Must keep cast if types are different.
     368                if ( !ResolvExpr::typesCompatible(
     369                                srcType,
     370                                strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) {
    366371                        return ast::mutate_field( expr, &ast::CastExpr::arg, ret );
    367372                }
     
    377382                }
    378383                // Must keep cast if types are different.
    379                 if ( !ResolvExpr::typesCompatibleIgnoreQualifiers(
     384                if ( !ResolvExpr::typesCompatible(
    380385                                dstType->stripReferences(),
    381386                                srcType->stripReferences() ) ) {
     
    390395        } else {
    391396                assert( 0 == diff );
    392                 // Remove useless generated casts.
    393                 if ( expr->isGenerated == ast::GeneratedFlag::GeneratedCast &&
    394                                 ResolvExpr::typesCompatible(
     397                // Must keep cast if types are different. (Or it is explicit.)
     398                if ( ast::ExplicitCast == expr->isGenerated ||
     399                                !ResolvExpr::typesCompatible(
    395400                                        expr->result,
    396401                                        expr->arg->result ) ) {
    397                         PRINT(
    398                                 std::cerr << "types are compatible, removing cast: " << expr << '\n';
    399                                 std::cerr << "-- " << expr->result << '\n';
    400                                 std::cerr << "-- " << expr->arg->result << std::endl;
    401                         )
    402                         auto argAsEnum = expr->arg.as<ast::EnumInstType>();
    403                         auto resultAsEnum = expr->result.as<ast::EnumInstType>();
    404                         if (argAsEnum && resultAsEnum) {
    405                                 if (argAsEnum->base->name != resultAsEnum->base->name) {
    406                                         return expr;
    407                                 }
    408                         }
    409                         return ast::mutate_field( expr->arg.get(),
    410                                         &ast::Expr::env, expr->env.get() );
    411                 }
    412                 return expr;
     402                        return expr;
     403                }
     404                PRINT(
     405                        std::cerr << "types are compatible, removing cast: " << expr << '\n';
     406                        std::cerr << "-- " << expr->result << '\n';
     407                        std::cerr << "-- " << expr->arg->result << std::endl;
     408                )
     409                return ast::mutate_field( expr->arg.get(),
     410                                &ast::Expr::env, expr->env.get() );
    413411        }
    414412}
     
    505503}
    506504
     505/// Recursively move an address expression underneath casts. Casts are not
     506/// lvalue expressions in C but are sometimes considered as such in Cforall,
     507/// (passes like InstantiateGeneric can add them.) - &(int) => (int*)&
     508ast::Expr const * moveAddressUnderCast( ast::AddressExpr const * expr ) {
     509        if ( !dynamic_cast<ast::CastExpr const *>( expr->arg.get() ) ) {
     510                return expr;
     511        }
     512        auto mutExpr = ast::mutate( expr );
     513        auto mutCast = strict_dynamic_cast<ast::CastExpr *>(
     514                        ast::mutate( mutExpr->arg.release() ) );
     515        mutExpr->arg = mutCast->arg;
     516        mutCast->arg = moveAddressUnderCast( mutExpr );
     517        mutCast->result = new ast::PointerType( mutCast->result );
     518        return mutCast;
     519}
     520
    507521ast::Expr const * CollapseAddressDeref::postvisit(
    508522                ast::AddressExpr const * expr ) {
     
    516530                        return ret;
    517531                }
    518         } else if ( auto cast = dynamic_cast<ast::CastExpr const *>( arg ) ) {
    519                 // Need to move cast to pointer type out a level since address of
    520                 // pointer is not valid C code (can be introduced in prior passes,
    521                 // e.g., InstantiateGeneric)
    522                 if ( ast::getPointerBase( cast->result ) ) {
    523                         auto mutExpr = ast::mutate( expr );
    524                         auto mutCast = strict_dynamic_cast<ast::CastExpr *>(
    525                                         ast::mutate( mutExpr->arg.release() ) );
    526                         mutExpr->arg = mutCast->arg;
    527                         mutCast->arg = mutExpr;
    528                         mutCast->result = new ast::PointerType( mutCast->result );
    529                         return mutCast;
    530                 }
     532        } else {
     533                return moveAddressUnderCast( expr );
    531534        }
    532535        return expr;
Note: See TracChangeset for help on using the changeset viewer.