Changes in src/GenPoly/Lvalue.cpp [bdf40650:b6f2e7ab]
- File:
-
- 1 edited
-
src/GenPoly/Lvalue.cpp (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Lvalue.cpp
rbdf40650 rb6f2e7ab 85 85 struct ReferenceConversions final : 86 86 public ast::WithConstTranslationUnit, 87 public ast::WithGuards, public ast::WithStmtsToAdd {87 public ast::WithGuards, public ast::WithStmtsToAdd<> { 88 88 ast::Expr const * postvisit( ast::CastExpr const * expr ); 89 89 ast::Expr const * postvisit( ast::AddressExpr const * expr ); … … 316 316 Warning::RvalueToReferenceConversion, toCString( expr->arg ) ); 317 317 318 // allowing conversion in the rvalue to const ref case319 // use the referenced-to type to create temp variables320 ast::Type const * targetType = dstType;321 for (int i = 0; i < diff; ++i) targetType = (strict_dynamic_cast<ast::ReferenceType const *>(targetType))->base;322 323 318 static UniqueName tmpNamer( "__ref_tmp_" ); 324 319 ast::ObjectDecl * tmp = new ast::ObjectDecl( expr->arg->location, 325 320 tmpNamer.newName(), 326 // ast::deepCopy( expr->arg->result ), 327 ast::deepCopy (targetType), 321 ast::deepCopy( expr->arg->result ), 328 322 new ast::SingleInit( expr->arg->location, expr->arg ) ); 329 323 PRINT( std::cerr << "make tmp: " << tmp << std::endl; ) … … 365 359 ret = new ast::AddressExpr( ret->location, ret ); 366 360 } 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. 371 366 return ast::mutate_field( expr, &ast::CastExpr::arg, ret ); 372 367 } … … 382 377 } 383 378 // Must keep cast if types are different. 384 if ( !ResolvExpr::typesCompatible (379 if ( !ResolvExpr::typesCompatibleIgnoreQualifiers( 385 380 dstType->stripReferences(), 386 381 srcType->stripReferences() ) ) { … … 395 390 } else { 396 391 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( 400 395 expr->result, 401 396 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; 411 413 } 412 414 } … … 503 505 } 504 506 505 /// Recursively move an address expression underneath casts. Casts are not506 /// 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 521 507 ast::Expr const * CollapseAddressDeref::postvisit( 522 508 ast::AddressExpr const * expr ) { … … 530 516 return ret; 531 517 } 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 } 534 531 } 535 532 return expr;
Note:
See TracChangeset
for help on using the changeset viewer.