Index: src/InitTweak/FixGlobalInit.cc
===================================================================
--- src/InitTweak/FixGlobalInit.cc	(revision 4d2434a3b1b9692aecc5c41cc41df0d3c37fbefb)
+++ src/InitTweak/FixGlobalInit.cc	(revision e3d1cc1cc41dfd30d0ace9e1dc26baf3cf303ced)
@@ -107,5 +107,5 @@
 
 			Statement * dtor = ctorInit->get_dtor();
-			if ( dtor && ! isInstrinsicSingleArgCallStmt( dtor ) ) {
+			if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
 				// don't need to call intrinsic dtor, because it does nothing, but
 				// non-intrinsic dtors must be called
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 4d2434a3b1b9692aecc5c41cc41df0d3c37fbefb)
+++ src/InitTweak/FixInit.cc	(revision e3d1cc1cc41dfd30d0ace9e1dc26baf3cf303ced)
@@ -26,4 +26,5 @@
 #include "SynTree/Type.h"
 #include "SynTree/Expression.h"
+#include "SynTree/Attribute.h"
 #include "SynTree/Statement.h"
 #include "SynTree/Initializer.h"
@@ -208,7 +209,5 @@
 				try {
 					*i = maybeMutate( *i, fixer );
-					// if (! fixer.staticDtorDecls.empty() ) {
-						translationUnit.splice( i, fixer.staticDtorDecls );
-					// }
+					translationUnit.splice( i, fixer.staticDtorDecls );
 				} catch( SemanticError &e ) {
 					errors.append( e );
@@ -446,44 +445,24 @@
 					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.
+						// we get memory errors with this approach. To remedy this, the static
+						// variable is hoisted when the destructor needs to be called.
 						//
 						// generate:
-						// T * __objName_static_ptrN;
+						// static T __objName_static_varN;
 						// void __objName_dtor_atexitN() {
-						//   __dtor(__objName_static_ptrN);
+						//   __dtor__...;
 						// }
 						// 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;
+						//     atexit(__objName_dtor_atexitN);
 						//   }
 						//   ...
 						// }
 
-						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
@@ -493,13 +472,4 @@
 						isUninitializedVar->fixUniqueId();
 
-						// __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 ) );
-
 						// __objName_uninitialized = false;
 						UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) );
@@ -511,6 +481,4 @@
 						std::list< Statement * > & body = initStmts->get_kids();
 						body.push_back( ctor );
-						body.push_back( new ExprStmt( noLabels, ptrAssign ) );
-						body.push_back( new ExprStmt( noLabels, callAtexit ) );
 						body.push_back( new ExprStmt( noLabels, setTrue ) );
 
@@ -520,7 +488,42 @@
 						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 );
+						if ( ctorInit->get_dtor() ) {
+							// if the object has a non-trivial destructor, have to
+							// hoist it and the object into the global space and
+							// call the destructor function with atexit.
+
+							Statement * dtorStmt = ctorInit->get_dtor()->clone();
+
+							// void __objName_dtor_atexitN(...) {...}
+							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 );
+
+							// atexit(dtor_atexit);
+							UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) );
+							callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
+
+							body.push_back( new ExprStmt( noLabels, callAtexit ) );
+
+							// hoist variable and dtor caller decls to list of decls that will be added into global scope
+							staticDtorDecls.push_back( objDecl );
+							staticDtorDecls.push_back( dtorCaller );
+
+							// need to rename object uniquely since it now appears
+							// at global scope and there could be multiple function-scoped
+							// static variables with the same name in different functions.
+							static UniqueName staticNamer( "_static_var" );
+							objDecl->set_mangleName( objDecl->get_mangleName() + staticNamer.newName() );
+
+							objDecl->set_init( NULL );
+							ctorInit->set_ctor( NULL );
+							delete ctorInit;
+
+							// xxx - temporary hack: need to return a declaration, but want to hoist the current object out of this scope
+							// create a new object which is never used
+							static UniqueName dummyNamer( "_dummy" );
+							ObjectDecl * dummy = new ObjectDecl( dummyNamer.newName(), DeclarationNode::Static, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), 0, std::list< Attribute * >{ new Attribute("unused") } );
+							return dummy;
+						}
 					} else {
 						stmtsToAddAfter.push_back( ctor );
@@ -582,5 +585,5 @@
 					assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
 					Statement * dtor = ctorInit->get_dtor();
-					if ( dtor && ! isInstrinsicSingleArgCallStmt( dtor ) ) {
+					if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
 						// don't need to call intrinsic dtor, because it does nothing, but
 						// non-intrinsic dtors must be called
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 4d2434a3b1b9692aecc5c41cc41df0d3c37fbefb)
+++ src/InitTweak/GenInit.cc	(revision e3d1cc1cc41dfd30d0ace9e1dc26baf3cf303ced)
@@ -172,7 +172,11 @@
 		// if in function, generate const size_t var
 		static UniqueName dimensionName( "_array_dim" );
+
+		// C doesn't allow variable sized arrays at global scope or for static variables,
+		// so don't hoist dimension.
+		if ( ! inFunction ) return;
+		if ( storageclass == DeclarationNode::Static ) return;
+
 		if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
-			if ( ! inFunction ) return;
-
 			if ( ! arrayType->get_dimension() ) return; // xxx - recursive call to hoist?
 
@@ -203,13 +207,4 @@
 		CtorDtor ctordtor;
 		mutateAll( translationUnit, ctordtor );
-	}
-
-	namespace {
-		Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
-			UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
-			expr->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
-			expr->get_args().splice( expr->get_args().end(), args );
-			return expr;
-		}
 	}
 
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 4d2434a3b1b9692aecc5c41cc41df0d3c37fbefb)
+++ src/InitTweak/InitTweak.cc	(revision e3d1cc1cc41dfd30d0ace9e1dc26baf3cf303ced)
@@ -5,4 +5,5 @@
 #include "SynTree/Initializer.h"
 #include "SynTree/Expression.h"
+#include "SynTree/Attribute.h"
 #include "GenPoly/GenPoly.h"
 
@@ -125,6 +126,10 @@
 
 	namespace {
+		/// given index i, dimension d, initializer init, and callExpr f, generates
+		///   if (i < d) f(..., init)
+		///   ++i;
+		/// so that only elements within the range of the array are constructed
 		template< typename OutIterator >
-		void dothething( UntypedExpr * callExpr, Expression * index, Expression * dimension, Initializer * init, OutIterator out ) {
+		void buildCallExpr( UntypedExpr * callExpr, Expression * index, Expression * dimension, Initializer * init, OutIterator out ) {
 			UntypedExpr * cond = new UntypedExpr( new NameExpr( "?<?") );
 			cond->get_args().push_back( index->clone() );
@@ -148,11 +153,13 @@
 			Expression * dimension = *idx++;
 
+			// xxx - may want to eventually issue a warning here if we can detect
+			// that the number of elements exceeds to dimension of the array
 			if ( idx == idxEnd ) {
 				if ( ListInit * listInit = dynamic_cast< ListInit * >( init ) ) {
 					for ( Initializer * init : *listInit ) {
-						dothething( callExpr->clone(), index, dimension, init, out );
+						buildCallExpr( callExpr->clone(), index, dimension, init, out );
 					}
 				} else {
-					dothething( callExpr->clone(), index, dimension, init, out );
+					buildCallExpr( callExpr->clone(), index, dimension, init, out );
 				}
 			} else {
@@ -166,4 +173,7 @@
 					throw SemanticError( "unbalanced list initializers" );
 				}
+
+				static UniqueName targetLabel( "L__autogen__" );
+				Label switchLabel( targetLabel.newName(), 0, std::list< Attribute * >{ new Attribute("unused") } );
 				for ( Initializer * init : *listInit ) {
 					Expression * condition;
@@ -178,8 +188,10 @@
 					std::list< Statement * > stmts;
 					build( callExpr, idx, idxEnd, init, back_inserter( stmts ) );
+					stmts.push_back( new BranchStmt( noLabels, switchLabel, BranchStmt::Break ) );
 					CaseStmt * caseStmt = new CaseStmt( noLabels, condition, stmts );
 					branches.push_back( caseStmt );
 				}
 				*out++ = new SwitchStmt( noLabels, index->clone(), branches );
+				*out++ = new NullStmt( std::list<Label>{ switchLabel } );
 			}
 		}
@@ -194,14 +206,13 @@
 	Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
 		if ( ! init ) return NULL;
-		std::list< Statement * > results;
-		build( dst, indices.begin(), indices.end(), init, back_inserter( results ) );
-		assert( results.size() <= 1 );
-		if ( results.empty() ) {
+		CompoundStmt * block = new CompoundStmt( noLabels );
+		build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) );
+		if ( block->get_kids().empty() ) {
+			delete block;
 			return NULL;
 		} else {
 			init = NULL; // init was consumed in creating the list init
-			return results.front();
-		}
-		return ! results.empty() ? results.front() : NULL;
+			return block;
+		}
 	}
 
@@ -280,5 +291,5 @@
 	}
 
-	bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
+	bool isIntrinsicSingleArgCallStmt( Statement * stmt ) {
 		std::list< Expression * > callExprs;
 		collectCtorDtorCalls( stmt, callExprs );
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision 4d2434a3b1b9692aecc5c41cc41df0d3c37fbefb)
+++ src/InitTweak/InitTweak.h	(revision e3d1cc1cc41dfd30d0ace9e1dc26baf3cf303ced)
@@ -41,5 +41,5 @@
 	/// Intended to be used for default ctor/dtor calls, but might have use elsewhere.
 	/// Currently has assertions that make it less than fully general.
-	bool isInstrinsicSingleArgCallStmt( Statement * expr );
+	bool isIntrinsicSingleArgCallStmt( Statement * expr );
 
 	/// get all Ctor/Dtor call expressions from a Statement
