Changes in src/GenPoly/Lvalue.cpp [b6f2e7ab:bdf40650]
- File:
-
- 1 edited
-
src/GenPoly/Lvalue.cpp (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Lvalue.cpp
rb6f2e7ab rbdf40650 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 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 318 323 static UniqueName tmpNamer( "__ref_tmp_" ); 319 324 ast::ObjectDecl * tmp = new ast::ObjectDecl( expr->arg->location, 320 325 tmpNamer.newName(), 321 ast::deepCopy( expr->arg->result ), 326 // ast::deepCopy( expr->arg->result ), 327 ast::deepCopy (targetType), 322 328 new ast::SingleInit( expr->arg->location, expr->arg ) ); 323 329 PRINT( std::cerr << "make tmp: " << tmp << std::endl; ) … … 359 365 ret = new ast::AddressExpr( ret->location, ret ); 360 366 } 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 ) ) { 366 371 return ast::mutate_field( expr, &ast::CastExpr::arg, ret ); 367 372 } … … 377 382 } 378 383 // Must keep cast if types are different. 379 if ( !ResolvExpr::typesCompatible IgnoreQualifiers(384 if ( !ResolvExpr::typesCompatible( 380 385 dstType->stripReferences(), 381 386 srcType->stripReferences() ) ) { … … 390 395 } else { 391 396 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( 395 400 expr->result, 396 401 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() ); 413 411 } 414 412 } … … 505 503 } 506 504 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 507 521 ast::Expr const * CollapseAddressDeref::postvisit( 508 522 ast::AddressExpr const * expr ) { … … 516 530 return ret; 517 531 } 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 ); 531 534 } 532 535 return expr;
Note:
See TracChangeset
for help on using the changeset viewer.