Changes in src/InitTweak/FixInit.cc [ee61248:a16764a6]
- File:
-
- 1 edited
-
src/InitTweak/FixInit.cc (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
ree61248 ra16764a6 68 68 typedef std::unordered_map< int, int > UnqCount; 69 69 70 struct SelfAssignChecker {71 void previsit( ApplicationExpr * appExpr );72 };73 74 70 struct InsertImplicitCalls : public WithTypeSubstitution { 75 71 /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which … … 239 235 240 236 void fix( std::list< Declaration * > & translationUnit, const std::string & filename, bool inLibrary ) { 241 PassVisitor<SelfAssignChecker> checker;242 acceptAll( translationUnit, checker );243 244 237 // fixes ConstructorInit for global variables. should happen before fixInitializers. 245 238 InitTweak::fixGlobalInit( translationUnit, filename, inLibrary ); … … 316 309 PassVisitor<FixCtorExprs> fixer; 317 310 mutateAll( translationUnit, fixer ); 318 }319 320 namespace {321 // Relatively simple structural comparison for expressions, needed to determine322 // if two expressions are "the same" (used to determine if self assignment occurs)323 struct StructuralChecker {324 Expression * stripCasts( Expression * expr ) {325 // this might be too permissive. It's possible that only particular casts are relevant.326 while ( CastExpr * cast = dynamic_cast< CastExpr * >( expr ) ) {327 expr = cast->arg;328 }329 return expr;330 }331 332 void previsit( Expression * ) {333 // anything else does not qualify334 isSimilar = false;335 }336 337 template<typename T>338 T * cast( Expression * node ) {339 // all expressions need to ignore casts, so this bit has been factored out340 return dynamic_cast< T * >( stripCasts( node ) );341 }342 343 // ignore casts344 void previsit( CastExpr * ) {}345 346 void previsit( MemberExpr * memExpr ) {347 if ( MemberExpr * otherMember = cast< MemberExpr >( other ) ) {348 if ( otherMember->member == memExpr->member ) {349 other = otherMember->aggregate;350 return;351 }352 }353 isSimilar = false;354 }355 356 void previsit( VariableExpr * varExpr ) {357 if ( VariableExpr * otherVar = cast< VariableExpr >( other ) ) {358 if ( otherVar->var == varExpr->var ) {359 return;360 }361 }362 isSimilar = false;363 }364 365 void previsit( AddressExpr * ) {366 if ( AddressExpr * addrExpr = cast< AddressExpr >( other ) ) {367 other = addrExpr->arg;368 return;369 }370 isSimilar = false;371 }372 373 Expression * other = nullptr;374 bool isSimilar = true;375 };376 377 bool structurallySimilar( Expression * e1, Expression * e2 ) {378 PassVisitor<StructuralChecker> checker;379 checker.pass.other = e2;380 e1->accept( checker );381 return checker.pass.isSimilar;382 }383 }384 385 void SelfAssignChecker::previsit( ApplicationExpr * appExpr ) {386 DeclarationWithType * function = getFunction( appExpr );387 if ( isAssignment( function ) ) {388 if ( appExpr->args.size() == 2 ) {389 // check for structural similarity (same variable use, ignore casts, etc. - but does not look too deeply, anything looking like a function is off limits)390 if ( structurallySimilar( appExpr->args.front(), appExpr->args.back() ) ) {391 SemanticWarning( appExpr->location, Warning::SelfAssignment, toCString( appExpr->args.front() ) );392 }393 }394 }395 311 } 396 312 … … 634 550 // add destructors after current statement 635 551 for ( Expression * dtor : dtors ) { 636 // take relevant bindings from environment637 assert( ! dtor->env );638 dtor->env = TypeSubstitution::newFromExpr( dtor, impCpCtorExpr->env );639 552 stmtsToAddAfter.push_back( new ExprStmt( dtor ) ); 640 553 } // for
Note:
See TracChangeset
for help on using the changeset viewer.