Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Lvalue.cpp

    rbdf40650 rb6f2e7ab  
    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 
    323318                static UniqueName tmpNamer( "__ref_tmp_" );
    324319                ast::ObjectDecl * tmp = new ast::ObjectDecl( expr->arg->location,
    325320                        tmpNamer.newName(),
    326                         // ast::deepCopy( expr->arg->result ),
    327                         ast::deepCopy (targetType),
     321                        ast::deepCopy( expr->arg->result ),
    328322                        new ast::SingleInit( expr->arg->location, expr->arg ) );
    329323                PRINT( std::cerr << "make tmp: " << tmp << std::endl; )
     
    365359                        ret = new ast::AddressExpr( ret->location, ret );
    366360                }
    367                 // Must keep cast if types are different.
    368                 if ( !ResolvExpr::typesCompatible(
    369                                 srcType,
    370                                 strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) {
     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.
    371366                        return ast::mutate_field( expr, &ast::CastExpr::arg, ret );
    372367                }
     
    382377                }
    383378                // Must keep cast if types are different.
    384                 if ( !ResolvExpr::typesCompatible(
     379                if ( !ResolvExpr::typesCompatibleIgnoreQualifiers(
    385380                                dstType->stripReferences(),
    386381                                srcType->stripReferences() ) ) {
     
    395390        } else {
    396391                assert( 0 == diff );
    397                 // Must keep cast if types are different. (Or it is explicit.)
    398                 if ( ast::ExplicitCast == expr->isGenerated ||
    399                                 !ResolvExpr::typesCompatible(
     392                // Remove useless generated casts.
     393                if ( expr->isGenerated == ast::GeneratedFlag::GeneratedCast &&
     394                                ResolvExpr::typesCompatible(
    400395                                        expr->result,
    401396                                        expr->arg->result ) ) {
    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() );
     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;
    411413        }
    412414}
     
    503505}
    504506
    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*)&
    508 ast::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 
    521507ast::Expr const * CollapseAddressDeref::postvisit(
    522508                ast::AddressExpr const * expr ) {
     
    530516                        return ret;
    531517                }
    532         } else {
    533                 return moveAddressUnderCast( expr );
     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                }
    534531        }
    535532        return expr;
Note: See TracChangeset for help on using the changeset viewer.