Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    ree61248 ra16764a6  
    6868                typedef std::unordered_map< int, int > UnqCount;
    6969
    70                 struct SelfAssignChecker {
    71                         void previsit( ApplicationExpr * appExpr );
    72                 };
    73 
    7470                struct InsertImplicitCalls : public WithTypeSubstitution {
    7571                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
     
    239235
    240236        void fix( std::list< Declaration * > & translationUnit, const std::string & filename, bool inLibrary ) {
    241                 PassVisitor<SelfAssignChecker> checker;
    242                 acceptAll( translationUnit, checker );
    243 
    244237                // fixes ConstructorInit for global variables. should happen before fixInitializers.
    245238                InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
     
    316309                        PassVisitor<FixCtorExprs> fixer;
    317310                        mutateAll( translationUnit, fixer );
    318                 }
    319 
    320                 namespace {
    321                         // Relatively simple structural comparison for expressions, needed to determine
    322                         // 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 qualify
    334                                         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 out
    340                                         return dynamic_cast< T * >( stripCasts( node ) );
    341                                 }
    342 
    343                                 // ignore casts
    344                                 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                         }
    395311                }
    396312
     
    634550                        // add destructors after current statement
    635551                        for ( Expression * dtor : dtors ) {
    636                                 // take relevant bindings from environment
    637                                 assert( ! dtor->env );
    638                                 dtor->env =  TypeSubstitution::newFromExpr( dtor, impCpCtorExpr->env );
    639552                                stmtsToAddAfter.push_back( new ExprStmt( dtor ) );
    640553                        } // for
Note: See TracChangeset for help on using the changeset viewer.