Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision ccb447e9609db81bd657114979c4e4e539785111)
+++ src/InitTweak/FixInit.cc	(revision 72e9222a9026d1f801ca6ee36c7a5b77604f5304)
@@ -161,4 +161,6 @@
 
 			virtual DeclarationWithType * mutate( ObjectDecl *objDecl );
+
+			std::list< Declaration * > staticDtorDecls;
 		};
 
@@ -199,5 +201,21 @@
 		void FixInit::fixInitializers( std::list< Declaration * > & translationUnit ) {
 			FixInit fixer;
-			mutateAll( translationUnit, fixer );
+
+			// can't use mutateAll, because need to insert declarations at top-level
+			// can't use DeclMutator, because sometimes need to insert IfStmt, etc.
+			SemanticError errors;
+			for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
+				try {
+					*i = maybeMutate( *i, fixer );
+					// if (! fixer.staticDtorDecls.empty() ) {
+						translationUnit.splice( i, fixer.staticDtorDecls );
+					// }
+				} catch( SemanticError &e ) {
+					errors.append( e );
+				} // try
+			} // for
+			if ( ! errors.isEmpty() ) {
+				throw errors;
+			} // if
 		}
 
@@ -427,16 +445,47 @@
 				if ( Statement * ctor = ctorInit->get_ctor() ) {
 					if ( objDecl->get_storageClass() == DeclarationNode::Static ) {
+						// originally wanted to take advantage of gcc nested functions, but
+						// we get memory errors with this approach. To remedy this, create a
+						// global static pointer that is set to refer to the object and make
+						// the dtor-caller function global so that.
+						//
 						// generate:
-						// static bool __objName_uninitialized = true;
-						// if (__objName_uninitialized) {
-						//   __ctor(__objName);
-						//   void dtor_atexit() {
-						//     __dtor(__objName);
+						// T * __objName_static_ptrN;
+						// void __objName_dtor_atexitN() {
+						//   __dtor(__objName_static_ptrN);
+						// }
+						// int f(...) {
+						//   ...
+						//   static T __objName;
+						//   static bool __objName_uninitialized = true;
+						//   if (__objName_uninitialized) {
+						//     __objName_ptr = &__objName;
+						//     __ctor(__objName);
+						//     on_exit(__objName_dtor_atexitN, &__objName);
+						//     __objName_uninitialized = false;
 						//   }
-						//   on_exit(dtorOnExit, &__objName);
-						//   __objName_uninitialized = false;
+						//   ...
 						// }
 
-						// generate first line
+						static UniqueName ptrNamer( "_static_ptr" );
+						static UniqueName dtorCallerNamer( "_dtor_atexit" );
+
+						// T * __objName_ptrN
+						ObjectDecl * objPtr = new ObjectDecl( objDecl->get_mangleName() + ptrNamer.newName(), DeclarationNode::Static, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), objDecl->get_type()->clone() ), 0 );
+						objPtr->fixUniqueId();
+
+						// void __objName_dtor_atexitN(...) {...}
+						// need to modify dtor call so that it refers to objPtr, since function will be global
+						Statement * dtorStmt = ctorInit->get_dtor()->clone();
+						ApplicationExpr * dtor = dynamic_cast< ApplicationExpr * >( InitTweak::getCtorDtorCall( dtorStmt ) );
+						assert( dtor );
+						delete dtor->get_args().front();
+						dtor->get_args().front() = new VariableExpr( objPtr );
+
+						FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
+						dtorCaller->fixUniqueId();
+						dtorCaller->get_statements()->get_kids().push_back( dtorStmt );
+
+						// static bool __objName_uninitialized = true
 						BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
 						SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant( boolType->clone(), "1" ) ), noDesignators );
@@ -444,10 +493,10 @@
 						isUninitializedVar->fixUniqueId();
 
-						// void dtor_atexit(...) {...}
-						FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + "_dtor_atexit", DeclarationNode::NoStorageClass, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
-						dtorCaller->fixUniqueId();
-						dtorCaller->get_statements()->get_kids().push_back( ctorInit->get_dtor()->clone() );
-
-						// on_exit(dtor_atexit);
+						// __objName_static_ptrN = &__objName;
+						UntypedExpr * ptrAssign = new UntypedExpr( new NameExpr( "?=?" ) );
+						ptrAssign->get_args().push_back( new VariableExpr( objPtr ) );
+						ptrAssign->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
+
+						// atexit(dtor_atexit);
 						UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) );
 						callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
@@ -462,5 +511,5 @@
 						std::list< Statement * > & body = initStmts->get_kids();
 						body.push_back( ctor );
-						body.push_back( new DeclStmt( noLabels, dtorCaller ) );
+						body.push_back( new ExprStmt( noLabels, ptrAssign ) );
 						body.push_back( new ExprStmt( noLabels, callAtexit ) );
 						body.push_back( new ExprStmt( noLabels, setTrue ) );
@@ -470,4 +519,8 @@
 						stmtsToAddAfter.push_back( new DeclStmt( noLabels, isUninitializedVar ) );
 						stmtsToAddAfter.push_back( ifStmt );
+
+						// add pointer and dtor caller decls to list of decls that will be added into global scope
+						staticDtorDecls.push_back( objPtr );
+						staticDtorDecls.push_back( dtorCaller );
 					} else {
 						stmtsToAddAfter.push_back( ctor );
Index: src/tests/init_once.c
===================================================================
--- src/tests/init_once.c	(revision ccb447e9609db81bd657114979c4e4e539785111)
+++ src/tests/init_once.c	(revision 72e9222a9026d1f801ca6ee36c7a5b77604f5304)
@@ -92,4 +92,8 @@
 init_once y = x;
 
+void static_variable() {
+	static init_once x;
+}
+
 int main() {
 	// local variables
@@ -179,4 +183,9 @@
 		}
 	}
+
+	// function-scoped static variable
+	for (int i = 0; i < 10; i++) {
+		static_variable();
+	}
 }
 
