Changeset babeeda
- Timestamp:
- Mar 1, 2018, 2:48:18 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- a8a2b0a
- Parents:
- 2103a51
- Location:
- src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/SemanticError.h
r2103a51 rbabeeda 37 37 38 38 constexpr const char * const WarningFormats[] = { 39 39 "self assignment of expression: %s", 40 40 }; 41 41 42 42 enum class Warning { 43 SelfAssignment, 43 44 NUMBER_OF_WARNINGS, //This MUST be the last warning 44 45 }; -
src/Common/utility.h
r2103a51 rbabeeda 162 162 } 163 163 164 #define toCString( ... ) toString( __VA_ARGS__ ).c_str() 165 164 166 // replace element of list with all elements of another list 165 167 template< typename T > -
src/InitTweak/FixInit.cc
r2103a51 rbabeeda 68 68 typedef std::unordered_map< int, int > UnqCount; 69 69 70 struct SelfAssignChecker { 71 void previsit( ApplicationExpr * appExpr ); 72 }; 73 70 74 struct InsertImplicitCalls : public WithTypeSubstitution { 71 75 /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which … … 235 239 236 240 void fix( std::list< Declaration * > & translationUnit, const std::string & filename, bool inLibrary ) { 241 PassVisitor<SelfAssignChecker> checker; 242 acceptAll( translationUnit, checker ); 243 237 244 // fixes ConstructorInit for global variables. should happen before fixInitializers. 238 245 InitTweak::fixGlobalInit( translationUnit, filename, inLibrary ); … … 309 316 PassVisitor<FixCtorExprs> fixer; 310 317 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 } 311 395 } 312 396
Note: See TracChangeset
for help on using the changeset viewer.