Index: src/InitTweak/FixInitNew.cpp
===================================================================
--- src/InitTweak/FixInitNew.cpp	(revision 0e707bd738702292a3fec65aa122d55d8eb482ba)
+++ src/InitTweak/FixInitNew.cpp	(revision 6a036eb371074e8ab361d2733b169c77d8013720)
@@ -357,21 +357,17 @@
 	// if two expressions are "the same" (used to determine if self assignment occurs)
 	struct StructuralChecker {
-		const ast::Expr * stripCasts( const ast::Expr * expr ) {
+		// Strip all casts and then dynamic_cast.
+		template<typename T>
+		static const T * cast( const ast::Expr * expr ) {
 			// this might be too permissive. It's possible that only particular casts are relevant.
 			while ( auto cast = dynamic_cast< const ast::CastExpr * >( expr ) ) {
 				expr = cast->arg;
 			}
-			return expr;
+			return dynamic_cast< const T * >( expr );
 		}
 
 		void previsit( const ast::Expr * ) {
 			// anything else does not qualify
-			isSimilar = false;
-		}
-
-		template<typename T>
-		T * cast( const ast::Expr * node ) {
-			// all expressions need to ignore casts, so this bit has been factored out
-			return dynamic_cast< T * >( stripCasts( node ) );
+			result = false;
 		}
 
@@ -380,5 +376,5 @@
 
 		void previsit( const ast::MemberExpr * memExpr ) {
-			if ( auto otherMember = cast< const ast::MemberExpr >( other ) ) {
+			if ( auto otherMember = cast< ast::MemberExpr >( other ) ) {
 				if ( otherMember->member == memExpr->member ) {
 					other = otherMember->aggregate;
@@ -386,33 +382,31 @@
 				}
 			}
-			isSimilar = false;
+			result = false;
 		}
 
 		void previsit( const ast::VariableExpr * varExpr ) {
-			if ( auto otherVar = cast< const ast::VariableExpr >( other ) ) {
+			if ( auto otherVar = cast< ast::VariableExpr >( other ) ) {
 				if ( otherVar->var == varExpr->var ) {
 					return;
 				}
 			}
-			isSimilar = false;
+			result = false;
 		}
 
 		void previsit( const ast::AddressExpr * ) {
-			if ( auto addrExpr = cast< const ast::AddressExpr >( other ) ) {
+			if ( auto addrExpr = cast< ast::AddressExpr >( other ) ) {
 				other = addrExpr->arg;
 				return;
 			}
-			isSimilar = false;
-		}
-
-		const ast::Expr * other = nullptr;
-		bool isSimilar = true;
+			result = false;
+		}
+
+		const ast::Expr * other;
+		bool result = true;
+		StructuralChecker( const ast::Expr * other ) : other(other) {}
 	};
 
 	bool structurallySimilar( const ast::Expr * e1, const ast::Expr * e2 ) {
-		ast::Pass<StructuralChecker> checker;
-		checker.core.other = e2;
-		e1->accept( checker );
-		return checker.core.isSimilar;
+		return ast::Pass<StructuralChecker>::read( e1, e2 );
 	}
 
