Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision b54ad9c66788ec2930ca0cac1989ef26b86a2708)
+++ src/InitTweak/FixInit.cc	(revision 2bfc6b281e65c5e8bdf4d021589a170c2cb15418)
@@ -56,4 +56,5 @@
 #include "SynTree/DeclReplacer.h"      // for DeclReplacer
 #include "SynTree/Visitor.h"           // for acceptAll, maybeAccept
+#include "Validate/FindSpecialDecls.h" // for dtorStmt, dtorStructDestroy
 
 bool ctordtorp = false; // print all debug
@@ -204,6 +205,4 @@
 			static void generate( std::list< Declaration * > & translationUnit );
 
-			void premutate( StructDecl * structDecl );
-
 			void premutate( FunctionDecl * funcDecl );
 			DeclarationWithType * postmutate( FunctionDecl * funcDecl );
@@ -227,8 +226,4 @@
 			bool isCtor = false; // true if current function is a constructor
 			StructDecl * structDecl = nullptr;
-
-			// special built-in functions necessary for this to work
-			StructDecl * dtorStruct = nullptr;
-			FunctionDecl * dtorStructDestroy = nullptr;
 		};
 
@@ -1019,10 +1014,4 @@
 		}
 
-		void GenStructMemberCalls::premutate( StructDecl * structDecl ) {
-			if ( ! dtorStruct && structDecl->name == "__Destructor" ) {
-				dtorStruct = structDecl;
-			}
-		}
-
 		void GenStructMemberCalls::premutate( FunctionDecl * funcDecl ) {
 			GuardValue( function );
@@ -1037,9 +1026,4 @@
 			unhandled.clear();
 			usedUninit.clear();
-
-			if ( ! dtorStructDestroy && funcDecl->name == "__destroy_Destructor" ) {
-				dtorStructDestroy = funcDecl;
-				return;
-			}
 
 			function = funcDecl;
@@ -1053,5 +1037,4 @@
 				if ( structType ) {
 					structDecl = structType->get_baseStruct();
-					if ( structDecl == dtorStruct ) return;
 					for ( Declaration * member : structDecl->get_members() ) {
 						if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {
@@ -1127,10 +1110,13 @@
 								// function->get_statements()->push_back( callStmt );
 
+								// Optimization: do not need to call intrinsic destructors on members
+								if ( isIntrinsicSingleArgCallStmt( callStmt ) ) continue;;
+
 								// __Destructor _dtor0 = { (void *)&b.a1, (void (*)(void *)_destroy_A };
 								std::list< Statement * > stmtsToAdd;
 
 								static UniqueName memberDtorNamer = { "__memberDtor" };
-								assertf( dtorStruct, "builtin __Destructor not found." );
-								assertf( dtorStructDestroy, "builtin __destroy_Destructor not found." );
+								assertf( Validate::dtorStruct, "builtin __Destructor not found." );
+								assertf( Validate::dtorStructDestroy, "builtin __destroy_Destructor not found." );
 
 								Expression * thisExpr = new CastExpr( new AddressExpr( new VariableExpr( thisParam ) ), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) );
@@ -1142,7 +1128,7 @@
 								Type * dtorType = new PointerType( Type::Qualifiers(), dtorFtype );
 
-								ObjectDecl * destructor = ObjectDecl::newObject( memberDtorNamer.newName(), new StructInstType( Type::Qualifiers(), dtorStruct ), new ListInit( { new SingleInit( thisExpr ), new SingleInit( new CastExpr( dtorExpr, dtorType ) ) } ) );
+								ObjectDecl * destructor = ObjectDecl::newObject( memberDtorNamer.newName(), new StructInstType( Type::Qualifiers(), Validate::dtorStruct ), new ListInit( { new SingleInit( thisExpr ), new SingleInit( new CastExpr( dtorExpr, dtorType ) ) } ) );
 								function->statements->push_front( new DeclStmt( destructor ) );
-								destructor->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( dtorStructDestroy ) } ) );
+								destructor->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( Validate::dtorStructDestroy ) } ) );
 
 								function->statements->kids.splice( function->statements->kids.begin(), stmtsToAdd );
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision b54ad9c66788ec2930ca0cac1989ef26b86a2708)
+++ src/InitTweak/GenInit.cc	(revision 2bfc6b281e65c5e8bdf4d021589a170c2cb15418)
@@ -15,31 +15,32 @@
 #include "GenInit.h"
 
-#include <stddef.h>                // for NULL
-#include <algorithm>               // for any_of
-#include <cassert>                 // for assert, strict_dynamic_cast, assertf
-#include <iterator>                // for back_inserter, inserter, back_inse...
-#include <list>                    // for _List_iterator, list
+#include <stddef.h>                    // for NULL
+#include <algorithm>                   // for any_of
+#include <cassert>                     // for assert, strict_dynamic_cast, assertf
+#include <iterator>                    // for back_inserter, inserter, back_inse...
+#include <list>                        // for _List_iterator, list
 
 #include "CodeGen/OperatorTable.h"
-#include "Common/PassVisitor.h"    // for PassVisitor, WithGuards, WithShort...
-#include "Common/SemanticError.h"  // for SemanticError
-#include "Common/UniqueName.h"     // for UniqueName
-#include "Common/utility.h"        // for ValueGuard, maybeClone
-#include "GenPoly/GenPoly.h"       // for getFunctionType, isPolyType
-#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::const_iter...
-#include "InitTweak.h"             // for isConstExpr, InitExpander, checkIn...
-#include "Parser/LinkageSpec.h"    // for isOverridable, C
+#include "Common/PassVisitor.h"        // for PassVisitor, WithGuards, WithShort...
+#include "Common/SemanticError.h"      // for SemanticError
+#include "Common/UniqueName.h"         // for UniqueName
+#include "Common/utility.h"            // for ValueGuard, maybeClone
+#include "GenPoly/GenPoly.h"           // for getFunctionType, isPolyType
+#include "GenPoly/ScopedSet.h"         // for ScopedSet, ScopedSet<>::const_iter...
+#include "InitTweak.h"                 // for isConstExpr, InitExpander, checkIn...
+#include "Parser/LinkageSpec.h"        // for isOverridable, C
 #include "ResolvExpr/Resolver.h"
-#include "SymTab/Autogen.h"        // for genImplicitCall, SizeType
-#include "SymTab/Mangler.h"        // for Mangler
-#include "SynTree/Declaration.h"   // for ObjectDecl, DeclarationWithType
-#include "SynTree/Expression.h"    // for VariableExpr, UntypedExpr, Address...
-#include "SynTree/Initializer.h"   // for ConstructorInit, SingleInit, Initi...
-#include "SynTree/Label.h"         // for Label
-#include "SynTree/Mutator.h"       // for mutateAll
-#include "SynTree/Statement.h"     // for CompoundStmt, ImplicitCtorDtorStmt
-#include "SynTree/Type.h"          // for Type, ArrayType, Type::Qualifiers
-#include "SynTree/Visitor.h"       // for acceptAll, maybeAccept
-#include "Tuples/Tuples.h"         // for maybeImpure
+#include "SymTab/Autogen.h"            // for genImplicitCall
+#include "SymTab/Mangler.h"            // for Mangler
+#include "SynTree/Declaration.h"       // for ObjectDecl, DeclarationWithType
+#include "SynTree/Expression.h"        // for VariableExpr, UntypedExpr, Address...
+#include "SynTree/Initializer.h"       // for ConstructorInit, SingleInit, Initi...
+#include "SynTree/Label.h"             // for Label
+#include "SynTree/Mutator.h"           // for mutateAll
+#include "SynTree/Statement.h"         // for CompoundStmt, ImplicitCtorDtorStmt
+#include "SynTree/Type.h"              // for Type, ArrayType, Type::Qualifiers
+#include "SynTree/Visitor.h"           // for acceptAll, maybeAccept
+#include "Tuples/Tuples.h"             // for maybeImpure
+#include "Validate/FindSpecialDecls.h" // for SizeType
 
 namespace InitTweak {
@@ -186,5 +187,5 @@
 
 			// need to resolve array dimensions in order to accurately determine if constexpr
-			ResolvExpr::findSingleExpression( arrayType->dimension, SymTab::SizeType->clone(), indexer );
+			ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
 			// array is variable-length when the dimension is not constexpr
 			arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
@@ -192,5 +193,5 @@
 			if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
 
-			ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, SymTab::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
+			ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, Validate::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
 			arrayDimension->get_type()->set_const( true );
 
