Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/Common/utility.h	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -252,8 +252,8 @@
 
 template< typename T >
-struct reverseIterate_t {
+struct reverse_iterate_t {
 	T& ref;
 
-	reverseIterate_t( T & ref ) : ref(ref) {}
+	reverse_iterate_t( T & ref ) : ref(ref) {}
 
 	typedef typename T::reverse_iterator iterator;
@@ -263,8 +263,44 @@
 
 template< typename T >
-reverseIterate_t< T > reverseIterate( T & ref ) {
-	return reverseIterate_t< T >( ref );
-}
-
+reverse_iterate_t< T > reverseIterate( T & ref ) {
+	return reverse_iterate_t< T >( ref );
+}
+
+// -----------------------------------------------------------------------------
+// Helper struct and function to support
+// for ( val : group_iterate( container1, container2, ... ) ) {}
+// syntax to have a for each that iterates multiple containers of the same length
+// TODO: update to use variadic arguments
+
+template< typename T1, typename T2 >
+struct group_iterate_t {
+	group_iterate_t( const T1 & v1, const T2 & v2 ) : args(v1, v2) {
+		assertf(v1.size() == v2.size(), "group iteration requires containers of the same size.");
+	};
+
+	struct iterator {
+		typedef std::tuple<typename T1::value_type, typename T2::value_type> value_type;
+		typedef typename T1::iterator T1Iter;
+		typedef typename T2::iterator T2Iter;
+		typedef std::tuple<T1Iter, T2Iter> IterTuple;
+		IterTuple it;
+		iterator( T1Iter i1, T2Iter i2 ) : it( i1, i2 ) {}
+		iterator operator++() {
+			return iterator( ++std::get<0>(it), ++std::get<1>(it) );
+		}
+		bool operator!=( const iterator &other ) const { return it != other.it; }
+		value_type operator*() const { return std::make_tuple( *std::get<0>(it), *std::get<1>(it) ); }
+	};
+	iterator begin() { return iterator( std::get<0>(args).begin(), std::get<1>(args).begin() ); }
+	iterator end() { return iterator( std::get<0>(args).end(), std::get<1>(args).end() ); }
+
+private:
+	std::tuple<T1, T2> args;
+};
+
+template< typename... Args >
+group_iterate_t<Args...> group_iterate( const Args &... args ) {
+	return group_iterate_t<Args...>(args...);
+}
 #endif // _UTILITY_H
 
Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/GenPoly/InstantiateGeneric.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -220,22 +220,23 @@
 			assert(paramType && "Aggregate parameters should be type expressions");
 
-			switch ( (*baseParam)->get_kind() ) {
-			case TypeDecl::Any: {
-				// substitute parameter for otype; makes the type concrete or dynamic depending on the parameter
+			if ( (*baseParam)->isComplete() ) {
+				// substitute parameter for complete (otype or sized dtype) type; makes the struct concrete or dynamic depending on the parameter
 				out.push_back( paramType->clone() );
 				gt |= isPolyType( paramType->get_type() ) ? genericType::dynamic : genericType::concrete;
-				break;
-			}
-			case TypeDecl::Dtype:
-				// can pretend that any dtype is `void`
-				out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
-				break;
-			case TypeDecl::Ftype:
-				// can pretend that any ftype is `void (*)(void)`
-				out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
-				break;
-			case TypeDecl::Ttype:
-				assertf( false, "Ttype parameters are not currently allowed as parameters to generic types." );
-				break;
+			} else switch ( (*baseParam)->get_kind() ) {
+				case TypeDecl::Dtype:
+					// can pretend that any incomplete dtype is `void`
+					out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
+					break;
+				case TypeDecl::Ftype:
+					// can pretend that any ftype is `void (*)(void)`
+					out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
+					break;
+				case TypeDecl::Ttype:
+					assertf( false, "Ttype parameters are not currently allowed as parameters to generic types." );
+					break;
+				case TypeDecl::Any:
+					assertf( false, "otype parameters handled by baseParam->isComplete()." );
+					break;
 			}
 		}
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/GenPoly/Specialize.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -35,7 +35,5 @@
 
 namespace GenPoly {
-	class Specializer;
 	class Specialize final : public PolyMutator {
-		friend class Specializer;
 	  public:
 		using PolyMutator::mutate;
@@ -47,40 +45,13 @@
 		// virtual Expression * mutate( CommaExpr *commaExpr );
 
-		Specializer * specializer = nullptr;
 		void handleExplicitParams( ApplicationExpr *appExpr );
+		Expression * createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams );
+		Expression * doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = nullptr );
+
+		std::string paramPrefix = "_p";
 	};
 
-	class Specializer {
-	  public:
-		Specializer( Specialize & spec ) : spec( spec ), env( spec.env ), stmtsToAdd( spec.stmtsToAdd ) {}
-		virtual bool needsSpecialization( Type * formalType, Type * actualType, TypeSubstitution * env ) = 0;
-		virtual Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) = 0;
-		virtual Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 );
-
-	  protected:
-		Specialize & spec;
-		std::string paramPrefix = "_p";
-		TypeSubstitution *& env;
-		std::list< Statement * > & stmtsToAdd;
-	};
-
-	// for normal polymorphic -> monomorphic function conversion
-	class PolySpecializer : public Specializer {
-	  public:
-		PolySpecializer( Specialize & spec ) : Specializer( spec ) {}
-		virtual bool needsSpecialization( Type * formalType, Type * actualType, TypeSubstitution * env ) override;
-		virtual Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) override;
-	};
-
-	// // for tuple -> non-tuple function conversion
-	class TupleSpecializer : public Specializer {
-	  public:
-		TupleSpecializer( Specialize & spec ) : Specializer( spec ) {}
-		virtual bool needsSpecialization( Type * formalType, Type * actualType, TypeSubstitution * env ) override;
-		virtual Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) override;
-	};
-
 	/// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type.
-	bool PolySpecializer::needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
+	bool needsPolySpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
 		if ( env ) {
 			using namespace ResolvExpr;
@@ -106,62 +77,16 @@
 	}
 
-	/// Generates a thunk that calls `actual` with type `funType` and returns its address
-	Expression * PolySpecializer::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
-		static UniqueName thunkNamer( "_thunk" );
-
-		FunctionType *newType = funType->clone();
-		if ( env ) {
-			// it is important to replace only occurrences of type variables that occur free in the
-			// thunk's type
-			env->applyFree( newType );
-		} // if
-		// create new thunk with same signature as formal type (C linkage, empty body)
-		FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( noLabels ), false, false );
-		thunkFunc->fixUniqueId();
-
-		// thunks may be generated and not used - silence warning with attribute
-		thunkFunc->get_attributes().push_back( new Attribute( "unused" ) );
-
-		// thread thunk parameters into call to actual function, naming thunk parameters as we go
-		UniqueName paramNamer( paramPrefix );
-		ApplicationExpr *appExpr = new ApplicationExpr( actual );
-		for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) {
-			(*param )->set_name( paramNamer.newName() );
-			appExpr->get_args().push_back( new VariableExpr( *param ) );
-		} // for
-		appExpr->set_env( maybeClone( env ) );
-		if ( inferParams ) {
-			appExpr->get_inferParams() = *inferParams;
-		} // if
-
-		// handle any specializations that may still be present
-		std::string oldParamPrefix = paramPrefix;
-		paramPrefix += "p";
-		// save stmtsToAdd in oldStmts
-		std::list< Statement* > oldStmts;
-		oldStmts.splice( oldStmts.end(), stmtsToAdd );
-		spec.handleExplicitParams( appExpr );
-		paramPrefix = oldParamPrefix;
-		// write any statements added for recursive specializations into the thunk body
-		thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd );
-		// restore oldStmts into stmtsToAdd
-		stmtsToAdd.splice( stmtsToAdd.end(), oldStmts );
-
-		// add return (or valueless expression) to the thunk
-		Statement *appStmt;
-		if ( funType->get_returnVals().empty() ) {
-			appStmt = new ExprStmt( noLabels, appExpr );
-		} else {
-			appStmt = new ReturnStmt( noLabels, appExpr );
-		} // if
-		thunkFunc->get_statements()->get_kids().push_back( appStmt );
-
-		// add thunk definition to queue of statements to add
-		stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );
-		// return address of thunk function as replacement expression
-		return new AddressExpr( new VariableExpr( thunkFunc ) );
-	}
-
-	Expression * Specializer::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
+	bool needsTupleSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
+		if ( FunctionType * ftype = getFunctionType( formalType ) ) {
+			return ftype->isTtype();
+		}
+		return false;
+	}
+
+	bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
+		return needsPolySpecialization( formalType, actualType, env ) || needsTupleSpecialization( formalType, actualType, env );
+	}
+
+	Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
 		assertf( actual->has_result(), "attempting to specialize an untyped expression" );
 		if ( needsSpecialization( formalType, actual->get_result(), env ) ) {
@@ -185,11 +110,4 @@
 	}
 
-	bool TupleSpecializer::needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
-		if ( FunctionType * ftype = getFunctionType( formalType ) ) {
-			return ftype->isTtype();
-		}
-		return false;
-	}
-
 	/// restructures arg to match the structure of a single formal parameter. Assumes that atomic types are compatible (as the Resolver should have ensured this)
 	template< typename OutIterator >
@@ -207,21 +125,26 @@
 
 	/// restructures the ttype argument to match the structure of the formal parameters of the actual function.
-	// [begin, end) are the formal parameters.
-	// args is the list of arguments currently given to the actual function, the last of which needs to be restructured.
+	/// [begin, end) are the formal parameters.
+	/// args is the list of arguments currently given to the actual function, the last of which needs to be restructured.
 	template< typename Iterator, typename OutIterator >
 	void fixLastArg( Expression * last, Iterator begin, Iterator end, OutIterator out ) {
-		// safe_dynamic_cast for the assertion
-		safe_dynamic_cast< TupleType * >( last->get_result() );
-		unsigned idx = 0;
-		for ( ; begin != end; ++begin ) {
-			DeclarationWithType * formal = *begin;
-			Type * formalType = formal->get_type();
-			matchOneFormal( last, idx, formalType, out );
-		}
-		delete last;
-	}
-
-	Expression * TupleSpecializer::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
-		static UniqueName thunkNamer( "_tupleThunk" );
+		if ( Tuples::isTtype( last->get_result() ) ) {
+			*out++ = last;
+		} else {
+			// safe_dynamic_cast for the assertion
+			safe_dynamic_cast< TupleType * >( last->get_result() );
+			unsigned idx = 0;
+			for ( ; begin != end; ++begin ) {
+				DeclarationWithType * formal = *begin;
+				Type * formalType = formal->get_type();
+				matchOneFormal( last, idx, formalType, out );
+			}
+			delete last;
+		}
+	}
+
+	/// Generates a thunk that calls `actual` with type `funType` and returns its address
+	Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
+		static UniqueName thunkNamer( "_thunk" );
 
 		FunctionType *newType = funType->clone();
@@ -253,5 +176,4 @@
 		std::list< DeclarationWithType * >::iterator formalEnd = funType->get_parameters().end();
 
-		Expression * last = nullptr;
 		for ( DeclarationWithType* param : thunkFunc->get_functionType()->get_parameters() ) {
 			// walk the parameters to the actual function alongside the parameters to the thunk to find the location where the ttype parameter begins to satisfy parameters in the actual function.
@@ -259,5 +181,5 @@
 			assertf( formalBegin != formalEnd, "Reached end of formal parameters before finding ttype parameter" );
 			if ( Tuples::isTtype((*formalBegin)->get_type()) ) {
-				last = new VariableExpr( param );
+				fixLastArg( new VariableExpr( param ), actualBegin, actualEnd, back_inserter( appExpr->get_args() ) );
 				break;
 			}
@@ -268,6 +190,4 @@
 			appExpr->get_args().push_back( new VariableExpr( param ) );
 		} // for
-		assert( last );
-		fixLastArg( last, actualBegin, actualEnd, back_inserter( appExpr->get_args() ) );
 		appExpr->set_env( maybeClone( env ) );
 		if ( inferParams ) {
@@ -281,5 +201,5 @@
 		std::list< Statement* > oldStmts;
 		oldStmts.splice( oldStmts.end(), stmtsToAdd );
-		spec.mutate( appExpr );
+		mutate( appExpr );
 		paramPrefix = oldParamPrefix;
 		// write any statements added for recursive specializations into the thunk body
@@ -311,5 +231,5 @@
 		std::list< Expression* >::iterator actual;
 		for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
-			*actual = specializer->doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() );
+			*actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() );
 		}
 	}
@@ -322,8 +242,10 @@
 			// create thunks for the inferred parameters
 			// don't need to do this for intrinsic calls, because they aren't actually passed
+			// need to handle explicit params before inferred params so that explicit params do not recieve a changed set of inferParams (and change them again)
+			// alternatively, if order starts to matter then copy appExpr's inferParams and pass them to handleExplicitParams.
+			handleExplicitParams( appExpr );
 			for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {
-				inferParam->second.expr = specializer->doSpecialization( inferParam->second.formalType, inferParam->second.expr, inferParam->second.inferParams.get() );
+				inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, inferParam->second.inferParams.get() );
 			}
-			handleExplicitParams( appExpr );
 		}
 		return appExpr;
@@ -333,5 +255,5 @@
 		addrExpr->get_arg()->acceptMutator( *this );
 		assert( addrExpr->has_result() );
-		addrExpr->set_arg( specializer->doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );
+		addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );
 		return addrExpr;
 	}
@@ -343,5 +265,5 @@
 			return castExpr;
 		}
-		Expression *specialized = specializer->doSpecialization( castExpr->get_result(), castExpr->get_arg() );
+		Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() );
 		if ( specialized != castExpr->get_arg() ) {
 			// assume here that the specialization incorporates the cast
@@ -370,11 +292,4 @@
 	void convertSpecializations( std::list< Declaration* >& translationUnit ) {
 		Specialize spec;
-
-		TupleSpecializer tupleSpec( spec );
-		spec.specializer = &tupleSpec;
-		mutateAll( translationUnit, spec );
-
-		PolySpecializer polySpec( spec );
-		spec.specializer = &polySpec;
 		mutateAll( translationUnit, spec );
 	}
Index: src/InitTweak/FixGlobalInit.cc
===================================================================
--- src/InitTweak/FixGlobalInit.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/InitTweak/FixGlobalInit.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -84,6 +84,6 @@
 			// for library code are run before constructors and destructors for user code,
 			// specify a priority when building the library. Priorities 0-100 are reserved by gcc.
-			ctorParameters.push_back( new ConstantExpr( Constant::from_int( 101 ) ) );
-			dtorParameters.push_back( new ConstantExpr( Constant::from_int( 101 ) ) );
+			ctorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) );
+			dtorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) );
 		}
 		initFunction = new FunctionDecl( "_init_" + fixedName, DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/InitTweak/FixInit.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -21,4 +21,5 @@
 #include <unordered_set>
 #include "InitTweak.h"
+#include "GenInit.h"
 #include "FixInit.h"
 #include "FixGlobalInit.h"
@@ -86,9 +87,8 @@
 			/// create and resolve ctor/dtor expression: fname(var, [cpArg])
 			Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
-			Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL );
 			/// true if type does not need to be copy constructed to ensure correctness
 			bool skipCopyConstruct( Type * type );
 			void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
-			void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
+			void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
 
 			TypeSubstitution * env;
@@ -398,12 +398,8 @@
 		Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
 			assert( var );
-			return makeCtorDtor( fname, new AddressExpr( new VariableExpr( var ) ), cpArg );
-		}
-
-		Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg ) {
-			assert( thisArg );
-			UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) );
-			untyped->get_args().push_back( thisArg );
-			if (cpArg) untyped->get_args().push_back( cpArg->clone() );
+			// arrays are not copy constructed, so this should always be an ExprStmt
+			ImplicitCtorDtorStmt * stmt = genCtorDtor( fname, var, cpArg );
+			ExprStmt * exprStmt = safe_dynamic_cast< ExprStmt * >( stmt->get_callStmt() );
+			Expression * untyped = exprStmt->get_expr();
 
 			// resolve copy constructor
@@ -420,5 +416,5 @@
 			} // if
 
-			delete untyped;
+			delete stmt;
 			return resolved;
 		}
@@ -456,6 +452,6 @@
 		}
 
-		void ResolveCopyCtors::destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) {
-			impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( ret ) ) );
+		void ResolveCopyCtors::destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) {
+			impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
 		}
 
@@ -487,5 +483,5 @@
 				if ( ! result->get_isLvalue() ) {
 					// destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
-					destructRet( new VariableExpr( ret ), impCpCtorExpr );
+					destructRet( ret, impCpCtorExpr );
 				}
 			} // for
@@ -515,5 +511,5 @@
 				last->set_expr( makeCtorDtor( "?{}", ret, last->get_expr() ) );
 
-				stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( new VariableExpr( ret ) ) ) );
+				stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
 			} // if
 
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/InitTweak/GenInit.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -247,4 +247,14 @@
 			managedTypes.insert( SymTab::Mangler::mangle( type->get_base() ) );
 		}
+	}
+
+	ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) {
+		// call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
+		assertf( objDecl, "genCtorDtor passed null objDecl" );
+		std::list< Statement * > stmts;
+		InitExpander srcParam( maybeClone( arg ) );
+		SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), fname, back_inserter( stmts ), objDecl );
+		assert( stmts.size() <= 1 );
+		return stmts.size() == 1 ? safe_dynamic_cast< ImplicitCtorDtorStmt * >( stmts.front() ) : nullptr;
 	}
 
Index: src/InitTweak/GenInit.h
===================================================================
--- src/InitTweak/GenInit.h	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/InitTweak/GenInit.h	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -28,4 +28,7 @@
 	void genInit( std::list< Declaration * > & translationUnit );
 
+  /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
+  ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
+
 	/// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
 	ConstructorInit * genCtorInit( ObjectDecl * objDecl );
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/InitTweak/InitTweak.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -327,4 +327,6 @@
 			} else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) {
 				return handleDerefCalledFunction( appExpr );
+			} else if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) {
+				return getCalledFunction( addrExpr->get_arg() );
 			}
 			return nullptr;
@@ -336,5 +338,5 @@
 		if ( ! appExpr ) return NULL;
 		DeclarationWithType * function = getCalledFunction( appExpr->get_function() );
-		assert( function );
+		assertf( function, "getCalledFunction returned nullptr: %s", toString( appExpr->get_function() ).c_str() );
 		// check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
 		// will call all member dtors, and some members may have a user defined dtor.
@@ -386,6 +388,13 @@
 		} else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( callExpr ) ) {
 			return callArg( untypedExpr, pos );
+		} else if ( TupleAssignExpr * tupleExpr = dynamic_cast< TupleAssignExpr * > ( callExpr ) ) {
+			std::list< Statement * > & stmts = tupleExpr->get_stmtExpr()->get_statements()->get_kids();
+			assertf( ! stmts.empty(), "TupleAssignExpr somehow has no statements." );
+			ExprStmt * stmt = safe_dynamic_cast< ExprStmt * >( stmts.back() );
+			TupleExpr * tuple = safe_dynamic_cast< TupleExpr * >( stmt->get_expr() );
+			assertf( ! tuple->get_exprs().empty(), "TupleAssignExpr somehow has empty tuple expr." );
+			return getCallArg( tuple->get_exprs().front(), pos );
 		} else {
-			assertf( false, "Unexpected expression type passed to getCallArg" );
+			assertf( false, "Unexpected expression type passed to getCallArg: %s", toString( callExpr ).c_str() );
 		}
 	}
@@ -538,4 +547,23 @@
 	}
 
+	FunctionDecl * isAssignment( Declaration * decl ) {
+		return isCopyFunction( decl, "?=?" );
+	}
+	FunctionDecl * isDestructor( Declaration * decl ) {
+		if ( isDestructor( decl->get_name() ) ) {
+			return dynamic_cast< FunctionDecl * >( decl );
+		}
+		return nullptr;
+	}
+	FunctionDecl * isDefaultConstructor( Declaration * decl ) {
+		if ( isConstructor( decl->get_name() ) ) {
+			if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
+				if ( func->get_functionType()->get_parameters().size() == 1 ) {
+					return func;
+				}
+			}
+		}
+		return nullptr;
+	}
 	FunctionDecl * isCopyConstructor( Declaration * decl ) {
 		return isCopyFunction( decl, "?{}" );
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/InitTweak/InitTweak.h	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -32,4 +32,7 @@
 	bool isCtorDtorAssign( const std::string & );
 
+	FunctionDecl * isAssignment( Declaration * decl );
+	FunctionDecl * isDestructor( Declaration * decl );
+	FunctionDecl * isDefaultConstructor( Declaration * decl );
 	FunctionDecl * isCopyConstructor( Declaration * decl );
 	FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname );
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/Parser/TypeData.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -57,4 +57,5 @@
 		aggregate.actuals = nullptr;
 		aggregate.fields = nullptr;
+		aggregate.body = false;
 		break;
 	  case AggregateInst:
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/ResolvExpr/Unify.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -123,31 +123,4 @@
 	}
 
-	struct CompleteTypeChecker : public Visitor {
-		virtual void visit( VoidType *basicType ) { status = false; }
-		virtual void visit( BasicType *basicType ) {}
-		virtual void visit( PointerType *pointerType ) {}
-		virtual void visit( ArrayType *arrayType ) { status = ! arrayType->get_isVarLen(); }
-		virtual void visit( FunctionType *functionType ) {}
-		virtual void visit( StructInstType *aggregateUseType ) { status = aggregateUseType->get_baseStruct()->has_body(); }
-		virtual void visit( UnionInstType *aggregateUseType ) { status = aggregateUseType->get_baseUnion()->has_body(); }
-		// xxx - enum inst does not currently contain a pointer to base, this should be fixed.
-		virtual void visit( EnumInstType *aggregateUseType ) { /* status = aggregateUseType->get_baseEnum()->hasBody(); */ }
-		virtual void visit( TraitInstType *aggregateUseType ) { assert( false ); }
-		virtual void visit( TypeInstType *aggregateUseType ) { status = aggregateUseType->get_baseType()->isComplete(); }
-		virtual void visit( TupleType *tupleType ) {} // xxx - not sure if this is right, might need to recursively check complete-ness
-		virtual void visit( TypeofType *typeofType ) { assert( false ); }
-		virtual void visit( AttrType *attrType ) { assert( false ); } // xxx - not sure what to do here
-		virtual void visit( VarArgsType *varArgsType ){} // xxx - is this right?
-		virtual void visit( ZeroType *zeroType ) {}
-		virtual void visit( OneType *oneType ) {}
-		bool status = true;
-	};
-	bool isComplete( Type * type ) {
-		CompleteTypeChecker checker;
-		assert( type );
-		type->accept( checker );
-		return checker.status;
-	}
-
 	bool tyVarCompatible( const TypeDecl::Data & data, Type *type, const SymTab::Indexer &indexer ) {
 		switch ( data.kind ) {
@@ -158,10 +131,10 @@
 			// type must also be complete
 			// xxx - should this also check that type is not a tuple type and that it's not a ttype?
-			return ! isFtype( type, indexer ) && (! data.isComplete || isComplete( type ));
+			return ! isFtype( type, indexer ) && (! data.isComplete || type->isComplete() );
 		  case TypeDecl::Ftype:
 			return isFtype( type, indexer );
 			case TypeDecl::Ttype:
 			// ttype unifies with any tuple type
-			return dynamic_cast< TupleType * >( type );
+			return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type );
 		} // switch
 		return false;
@@ -488,10 +461,10 @@
 	}
 
-	template< typename Iterator >
-	std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end ) {
+	template< typename Iterator, typename Func >
+	std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end, Func & toType ) {
 		std::list< Type * > types;
 		for ( ; begin != end; ++begin ) {
 			// it's guaranteed that a ttype variable will be bound to a flat tuple, so ensure that this results in a flat tuple
-			flatten( (*begin)->get_type(), back_inserter( types ) );
+			flatten( toType( *begin ), back_inserter( types ) );
 		}
 		return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) );
@@ -500,4 +473,5 @@
 	template< typename Iterator1, typename Iterator2 >
 	bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
+		auto get_type = [](DeclarationWithType * dwt){ return dwt->get_type(); };
 		for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
 			Type * t1 = (*list1Begin)->get_type();
@@ -509,8 +483,8 @@
 			if ( isTtype1 && ! isTtype2 ) {
 				// combine all of the things in list2, then unify
-				return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else if ( isTtype2 && ! isTtype1 ) {
 				// combine all of the things in list1, then unify
-				return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
 				return false;
@@ -522,5 +496,5 @@
 			Type * t1 = (*list1Begin)->get_type();
 			if ( Tuples::isTtype( t1 ) ) {
-				return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else return false;
 		} else if ( list2Begin != list2End ) {
@@ -528,5 +502,5 @@
 			Type * t2 = (*list2Begin)->get_type();
 			if ( Tuples::isTtype( t2 ) ) {
-				return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+				return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 			} else return false;
 		} else {
@@ -665,21 +639,54 @@
 	template< typename Iterator1, typename Iterator2 >
 	bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
+		auto get_type = [](Type * t) { return t; };
 		for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
-			Type *commonType = 0;
-			if ( ! unifyInexact( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, widenMode, indexer, commonType ) ) {
+			Type * t1 = *list1Begin;
+			Type * t2 = *list2Begin;
+			bool isTtype1 = Tuples::isTtype( t1 );
+			bool isTtype2 = Tuples::isTtype( t2 );
+			// xxx - assumes ttype must be last parameter
+			// xxx - there may be a nice way to refactor this, but be careful because the argument positioning might matter in some cases.
+			if ( isTtype1 && ! isTtype2 ) {
+				// combine all of the things in list2, then unify
+				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+			} else if ( isTtype2 && ! isTtype1 ) {
+				// combine all of the things in list1, then unify
+				return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+			} else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
 				return false;
-			}
-			delete commonType;
+			} // if
+
 		} // for
-		if ( list1Begin != list1End || list2Begin != list2End ) {
-			return false;
+		if ( list1Begin != list1End ) {
+			// try unifying empty tuple type with ttype
+			Type * t1 = *list1Begin;
+			if ( Tuples::isTtype( t1 ) ) {
+				return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+			} else return false;
+		} else if ( list2Begin != list2End ) {
+			// try unifying empty tuple type with ttype
+			Type * t2 = *list2Begin;
+			if ( Tuples::isTtype( t2 ) ) {
+				return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+			} else return false;
 		} else {
 			return true;
-		} //if
+		} // if
 	}
 
 	void Unify::visit(TupleType *tupleType) {
 		if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
-			result = unifyList( tupleType->get_types().begin(), tupleType->get_types().end(), otherTuple->get_types().begin(), otherTuple->get_types().end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer );
+			std::unique_ptr<TupleType> flat1( tupleType->clone() );
+			std::unique_ptr<TupleType> flat2( otherTuple->clone() );
+			std::list<Type *> types1, types2;
+
+			TtypeExpander expander( env );
+			flat1->acceptMutator( expander );
+			flat2->acceptMutator( expander );
+
+			flatten( flat1.get(), back_inserter( types1 ) );
+			flatten( flat2.get(), back_inserter( types2 ) );
+
+			result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer );
 		} // if
 	}
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/SymTab/Autogen.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -25,4 +25,5 @@
 #include "Autogen.h"
 #include "GenPoly/ScopedSet.h"
+#include "Common/ScopedMap.h"
 #include "SymTab/Mangler.h"
 #include "GenPoly/DeclMutator.h"
@@ -30,6 +31,16 @@
 namespace SymTab {
 	Type * SizeType = 0;
-
-	class AutogenerateRoutines : public Visitor {
+	typedef ScopedMap< std::string, bool > TypeMap;
+
+	/// Data used to generate functions generically. Specifically, the name of the generated function, a function which generates the routine protoype, and a map which contains data to determine whether a function should be generated.
+	struct FuncData {
+		typedef FunctionType * (*TypeGen)( Type * );
+		FuncData( const std::string & fname, const TypeGen & genType, TypeMap & map ) : fname( fname ), genType( genType ), map( map ) {}
+		std::string fname;
+		TypeGen genType;
+		TypeMap & map;
+	};
+
+	class AutogenerateRoutines final : public Visitor {
 	  public:
 		std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
@@ -37,4 +48,6 @@
 		typedef Visitor Parent;
 		using Parent::visit;
+
+		AutogenerateRoutines();
 
 		virtual void visit( EnumDecl *enumDecl );
@@ -57,4 +70,9 @@
 		std::set< std::string > structsDone;
 		unsigned int functionNesting = 0;     // current level of nested functions
+		/// Note: the following maps could be ScopedSets, but it should be easier to work
+		/// deleted functions in if they are maps, since the value false can be inserted
+		/// at the current scope without affecting outer scopes or requiring copies.
+		TypeMap copyable, assignable, constructable, destructable;
+		std::vector< FuncData > data;
 	};
 
@@ -144,4 +162,66 @@
 		decl->fixUniqueId();
 		return decl;
+	}
+
+	/// inserts base type of first argument into map if pred(funcDecl) is true
+	void insert( FunctionDecl *funcDecl, TypeMap & map, FunctionDecl * (*pred)(Declaration *) ) {
+		// insert type into constructable, etc. map if appropriate
+		if ( pred( funcDecl ) ) {
+			FunctionType * ftype = funcDecl->get_functionType();
+			assert( ! ftype->get_parameters().empty() );
+			Type * t = safe_dynamic_cast< PointerType * >( ftype->get_parameters().front()->get_type() )->get_base();
+			map.insert( Mangler::mangleType( t ), true );
+		}
+	}
+
+	/// using map and t, determines if is constructable, etc.
+	bool lookup( const TypeMap & map, Type * t ) {
+		if ( dynamic_cast< PointerType * >( t ) ) {
+			// will need more complicated checking if we want this to work with pointer types, since currently
+			return true;
+		} else if ( ArrayType * at = dynamic_cast< ArrayType * >( t ) ) {
+			// an array's constructor, etc. is generated on the fly based on the base type's constructor, etc.
+			return lookup( map, at->get_base() );
+		}
+		TypeMap::const_iterator it = map.find( Mangler::mangleType( t ) );
+		if ( it != map.end() ) return it->second;
+		// something that does not appear in the map is by default not constructable, etc.
+		return false;
+	}
+
+	/// using map and aggr, examines each member to determine if constructor, etc. should be generated
+	template<typename AggrDecl>
+	bool shouldGenerate( const TypeMap & map, AggrDecl * aggr ) {
+		for ( Declaration * dcl : aggr->get_members() ) {
+			if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( dcl ) ) {
+				if ( ! lookup( map, dwt->get_type() ) ) return false;
+			}
+		}
+		return true;
+	}
+
+	/// data structure for abstracting the generation of special functions
+	template< typename OutputIterator >
+	struct FuncGenerator {
+		StructDecl *aggregateDecl;
+		StructInstType *refType;
+		unsigned int functionNesting;
+		const std::list< TypeDecl* > & typeParams;
+		OutputIterator out;
+		FuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : aggregateDecl( aggregateDecl ), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {}
+
+		/// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map.
+		void gen( const FuncData & data ) {
+			if ( ! shouldGenerate( data.map, aggregateDecl ) ) return;
+			FunctionType * ftype = data.genType( refType );
+			cloneAll( typeParams, ftype->get_forall() );
+			*out++ = genFunc( data.fname, ftype, functionNesting );
+			data.map.insert( Mangler::mangleType( refType ), true );
+		}
+	};
+
+	template< typename OutputIterator >
+	FuncGenerator<OutputIterator> makeFuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) {
+		return FuncGenerator<OutputIterator>( aggregateDecl, refType, functionNesting, typeParams, out );
 	}
 
@@ -308,28 +388,17 @@
 
 	/// generates struct constructors, destructor, and assignment functions
-	void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
-
+	void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
 		// Make function polymorphic in same parameters as generic struct, if applicable
 		const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
 		bool isDynamicLayout = hasDynamicLayout( aggregateDecl );  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
 
-		// T ?=?(T *, T);
-		FunctionType *assignType = genAssignType( refType );
-		cloneAll( typeParams, assignType->get_forall() );
-
-		// void ?{}(T *); void ^?{}(T *);
-		FunctionType *ctorType = genDefaultType( refType );
-		cloneAll( typeParams, ctorType->get_forall() );
-		FunctionType *dtorType = genDefaultType( refType );
-		cloneAll( typeParams, dtorType->get_forall() );
-
-		// void ?{}(T *, T);
-		FunctionType *copyCtorType = genCopyType( refType );
-		cloneAll( typeParams, copyCtorType->get_forall() );
-
-		FunctionDecl *assignDecl = genFunc( "?=?", assignType, functionNesting );
-		FunctionDecl *ctorDecl = genFunc( "?{}", ctorType, functionNesting );
-		FunctionDecl *copyCtorDecl = genFunc( "?{}", copyCtorType, functionNesting );
-		FunctionDecl *dtorDecl = genFunc( "^?{}", dtorType, functionNesting );
+		// generate each of the functions based on the supplied FuncData objects
+		std::list< FunctionDecl * > newFuncs;
+		auto generator = makeFuncGenerator( aggregateDecl, refType, functionNesting, typeParams, back_inserter( newFuncs ) );
+		for ( const FuncData & d : data ) {
+			generator.gen( d );
+		}
+		// field ctors are only generated if default constructor and copy constructor are both generated
+		unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return InitTweak::isConstructor( dcl->get_name() ); } );
 
 		if ( functionNesting == 0 ) {
@@ -338,54 +407,58 @@
 			// Note: this is necessary if we want structs which contain
 			// generic (otype) structs as members.
-			addForwardDecl( assignDecl, declsToAdd );
-			addForwardDecl( ctorDecl, declsToAdd );
-			addForwardDecl( copyCtorDecl, declsToAdd );
-			addForwardDecl( dtorDecl, declsToAdd );
+			for ( FunctionDecl * dcl : newFuncs ) {
+				addForwardDecl( dcl, declsToAdd );
+			}
+		}
+
+		for ( FunctionDecl * dcl : newFuncs ) {
+			// generate appropriate calls to member ctor, assignment
+			// destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor
+			if ( ! InitTweak::isDestructor( dcl->get_name() ) ) {
+				makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl, isDynamicLayout );
+			} else {
+				makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, isDynamicLayout, false );
+			}
+			if ( InitTweak::isAssignment( dcl->get_name() ) ) {
+				// assignment needs to return a value
+				FunctionType * assignType = dcl->get_functionType();
+				assert( assignType->get_parameters().size() == 2 );
+				ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( assignType->get_parameters().back() );
+				dcl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
+			}
+			declsToAdd.push_back( dcl );
 		}
 
 		// create constructors which take each member type as a parameter.
 		// for example, for struct A { int x, y; }; generate
-		// void ?{}(A *, int) and void ?{}(A *, int, int)
-		std::list<Declaration *> memCtors;
-		FunctionType * memCtorType = ctorType->clone();
-		for ( std::list<Declaration *>::iterator i = aggregateDecl->get_members().begin(); i != aggregateDecl->get_members().end(); ++i ) {
-			DeclarationWithType * member = dynamic_cast<DeclarationWithType *>( *i );
-			assert( member );
-			if ( isUnnamedBitfield( dynamic_cast< ObjectDecl * > ( member ) ) ) {
-				// don't make a function whose parameter is an unnamed bitfield
-				continue;
-			} else if ( member->get_name() == "" ) {
-				// don't assign to anonymous members
-				// xxx - this is a temporary fix. Anonymous members tie into
-				// our inheritance model. I think the correct way to handle this is to
-				// cast the structure to the type of the member and let the resolver
-				// figure out whether it's valid and have a pass afterwards that fixes
-				// the assignment to use pointer arithmetic with the offset of the
-				// member, much like how generic type members are handled.
-				continue;
-			}
-			memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) );
-			FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting );
-			makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, isDynamicLayout );
-			memCtors.push_back( ctor );
-		}
-		delete memCtorType;
-
-		// generate appropriate calls to member ctor, assignment
-		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), assignDecl, isDynamicLayout );
-		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctorDecl, isDynamicLayout );
-		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), copyCtorDecl, isDynamicLayout );
-		// needs to do everything in reverse, so pass "forward" as false
-		makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, isDynamicLayout, false );
-
-		assert( assignType->get_parameters().size() == 2 );
-		ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( assignType->get_parameters().back() );
-		assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
-
-		declsToAdd.push_back( ctorDecl );
-		declsToAdd.push_back( copyCtorDecl );
-		declsToAdd.push_back( dtorDecl );
-		declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return
-		declsToAdd.splice( declsToAdd.end(), memCtors );
+		//   void ?{}(A *, int) and void ?{}(A *, int, int)
+		// Field constructors are only generated if default and copy constructor
+		// are generated, since they need access to both
+		if ( numCtors == 2 ) {
+			FunctionType * memCtorType = genDefaultType( refType );
+			cloneAll( typeParams, memCtorType->get_forall() );
+			for ( std::list<Declaration *>::iterator i = aggregateDecl->get_members().begin(); i != aggregateDecl->get_members().end(); ++i ) {
+				DeclarationWithType * member = dynamic_cast<DeclarationWithType *>( *i );
+				assert( member );
+				if ( isUnnamedBitfield( dynamic_cast< ObjectDecl * > ( member ) ) ) {
+					// don't make a function whose parameter is an unnamed bitfield
+					continue;
+				} else if ( member->get_name() == "" ) {
+					// don't assign to anonymous members
+					// xxx - this is a temporary fix. Anonymous members tie into
+					// our inheritance model. I think the correct way to handle this is to
+					// cast the structure to the type of the member and let the resolver
+					// figure out whether it's valid and have a pass afterwards that fixes
+					// the assignment to use pointer arithmetic with the offset of the
+					// member, much like how generic type members are handled.
+					continue;
+				}
+				memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) );
+				FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting );
+				makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, isDynamicLayout );
+				declsToAdd.push_back( ctor );
+			}
+			delete memCtorType;
+		}
 	}
 
@@ -481,4 +554,13 @@
 	}
 
+	AutogenerateRoutines::AutogenerateRoutines() {
+		// the order here determines the order that these functions are generated.
+		// assignment should come last since it uses copy constructor in return.
+		data.push_back( FuncData( "?{}", genDefaultType, constructable ) );
+		data.push_back( FuncData( "?{}", genCopyType, copyable ) );
+		data.push_back( FuncData( "^?{}", genDefaultType, destructable ) );
+		data.push_back( FuncData( "?=?", genAssignType, assignable ) );
+	}
+
 	void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
 		if ( ! enumDecl->get_members().empty() ) {
@@ -491,11 +573,13 @@
 
 	void AutogenerateRoutines::visit( StructDecl *structDecl ) {
-		if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
+		if ( structDecl->has_body() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
 			StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
 			for ( TypeDecl * typeDecl : structDecl->get_parameters() ) {
+				// need to visit assertions so that they are added to the appropriate maps
+				acceptAll( typeDecl->get_assertions(), *this );
 				structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
 			}
 			structInst.set_baseStruct( structDecl );
-			makeStructFunctions( structDecl, &structInst, functionNesting, declsToAdd );
+			makeStructFunctions( structDecl, &structInst, functionNesting, declsToAdd, data );
 			structsDone.insert( structDecl->get_name() );
 		} // if
@@ -564,4 +648,10 @@
 
 	void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
+		// record the existence of this function as appropriate
+		insert( functionDecl, constructable, InitTweak::isDefaultConstructor );
+		insert( functionDecl, assignable, InitTweak::isAssignment );
+		insert( functionDecl, copyable, InitTweak::isCopyConstructor );
+		insert( functionDecl, destructable, InitTweak::isDestructor );
+
 		maybeAccept( functionDecl->get_functionType(), *this );
 		acceptAll( functionDecl->get_oldDecls(), *this );
@@ -572,5 +662,13 @@
 
 	void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
+		constructable.beginScope();
+		assignable.beginScope();
+		copyable.beginScope();
+		destructable.beginScope();
 		visitStatement( compoundStmt );
+		constructable.endScope();
+		assignable.endScope();
+		copyable.endScope();
+		destructable.endScope();
 	}
 
Index: src/SymTab/FixFunction.cc
===================================================================
--- src/SymTab/FixFunction.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/SymTab/FixFunction.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -25,5 +25,6 @@
 
 	DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) {
-		ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
+		ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0, functionDecl->get_attributes() );
+		functionDecl->get_attributes().clear();
 		delete functionDecl;
 		return pointer;
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/SymTab/Validate.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -114,5 +114,5 @@
 		LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
 	  private:
-  		using Indexer::visit;
+  		using Parent::visit;
 		void visit( StructInstType *structInst ) final;
 		void visit( UnionInstType *unionInst ) final;
@@ -131,11 +131,12 @@
 
 	/// Replaces array and function types in forall lists by appropriate pointer type
-	class Pass3 : public Indexer {
+	class Pass3 final : public Indexer {
 		typedef Indexer Parent;
 	  public:
+	  	using Parent::visit;
 		Pass3( const Indexer *indexer );
 	  private:
-		virtual void visit( ObjectDecl *object );
-		virtual void visit( FunctionDecl *func );
+		virtual void visit( ObjectDecl *object ) override;
+		virtual void visit( FunctionDecl *func ) override;
 
 		const Indexer *indexer;
@@ -375,12 +376,12 @@
 	}
 
-	void LinkReferenceToTypes::visit( TraitInstType *contextInst ) {
-		Parent::visit( contextInst );
-		if ( contextInst->get_name() == "sized" ) {
+	void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
+		Parent::visit( traitInst );
+		if ( traitInst->get_name() == "sized" ) {
 			// "sized" is a special trait with no members - just flick the sized status on for the type variable
-			if ( contextInst->get_parameters().size() != 1 ) {
-				throw SemanticError( "incorrect number of context parameters: ", contextInst );
+			if ( traitInst->get_parameters().size() != 1 ) {
+				throw SemanticError( "incorrect number of trait parameters: ", traitInst );
 			}
-			TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( contextInst->get_parameters().front() );
+			TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() );
 			TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() );
 			TypeDecl * decl = inst->get_baseType();
@@ -389,27 +390,33 @@
 			return;
 		}
-		TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() );
-		if ( ! ctx ) {
-			throw SemanticError( "use of undeclared context " + contextInst->get_name() );
-		} // if
-		for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
-			for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
-				if ( TraitInstType *otherCtx = dynamic_cast< TraitInstType * >(*assert ) ) {
-					cloneAll( otherCtx->get_members(), contextInst->get_members() );
-				} else {
-					contextInst->get_members().push_back( (*assert )->clone() );
-				} // if
+		TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
+		if ( ! traitDecl ) {
+			throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
+		} // if
+		if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
+			throw SemanticError( "incorrect number of trait parameters: ", traitInst );
+		} // if
+
+		for ( TypeDecl * td : traitDecl->get_parameters() ) {
+			for ( DeclarationWithType * assert : td->get_assertions() ) {
+				traitInst->get_members().push_back( assert->clone() );
 			} // for
 		} // for
 
-		if ( ctx->get_parameters().size() != contextInst->get_parameters().size() ) {
-			throw SemanticError( "incorrect number of context parameters: ", contextInst );
-		} // if
-
-		// need to clone members of the context for ownership purposes
+		// need to clone members of the trait for ownership purposes
 		std::list< Declaration * > members;
-		std::transform( ctx->get_members().begin(), ctx->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
-
-		applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( contextInst->get_members() ) );
+		std::transform( traitDecl->get_members().begin(), traitDecl->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
+
+		applySubstitution( traitDecl->get_parameters().begin(), traitDecl->get_parameters().end(), traitInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( traitInst->get_members() ) );
+
+		// need to carry over the 'sized' status of each decl in the instance
+		for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) {
+			TypeExpr * expr = safe_dynamic_cast< TypeExpr * >( std::get<1>(p) );
+			if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
+				TypeDecl * formalDecl = std::get<0>(p);
+				TypeDecl * instDecl = inst->get_baseType();
+				if ( formalDecl->get_sized() ) instDecl->set_sized( true );
+			}
+		}
 	}
 
@@ -457,25 +464,26 @@
 	}
 
-	/// Fix up assertions
-	void forallFixer( Type *func ) {
-		for ( Type::ForallList::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
+	/// Fix up assertions - flattens assertion lists, removing all trait instances
+	void forallFixer( Type * func ) {
+		for ( TypeDecl * type : func->get_forall() ) {
 			std::list< DeclarationWithType * > toBeDone, nextRound;
-			toBeDone.splice( toBeDone.end(), (*type )->get_assertions() );
+			toBeDone.splice( toBeDone.end(), type->get_assertions() );
 			while ( ! toBeDone.empty() ) {
-				for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
-					if ( TraitInstType *ctx = dynamic_cast< TraitInstType * >( (*assertion )->get_type() ) ) {
-						for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
-							DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
-							assert( dwt );
+				for ( DeclarationWithType * assertion : toBeDone ) {
+					if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
+						// expand trait instance into all of its members
+						for ( Declaration * member : traitInst->get_members() ) {
+							DeclarationWithType *dwt = safe_dynamic_cast< DeclarationWithType * >( member );
 							nextRound.push_back( dwt->clone() );
 						}
-						delete ctx;
+						delete traitInst;
 					} else {
+						// pass assertion through
 						FixFunction fixer;
-						*assertion = (*assertion )->acceptMutator( fixer );
+						assertion = assertion->acceptMutator( fixer );
 						if ( fixer.get_isVoid() ) {
 							throw SemanticError( "invalid type void in assertion of function ", func );
 						}
-						(*type )->get_assertions().push_back( *assertion );
+						type->get_assertions().push_back( assertion );
 					} // if
 				} // for
@@ -629,5 +637,8 @@
 		if ( FunctionType *funtype = dynamic_cast<FunctionType *>( ret->get_type() ) ) {
 			// replace the current object declaration with a function declaration
-			return new FunctionDecl( ret->get_name(), ret->get_storageClass(), ret->get_linkage(), funtype, 0, ret->get_isInline(), ret->get_isNoreturn() );
+			FunctionDecl * newDecl = new FunctionDecl( ret->get_name(), ret->get_storageClass(), ret->get_linkage(), funtype, 0, ret->get_isInline(), ret->get_isNoreturn(), objDecl->get_attributes() );
+			objDecl->get_attributes().clear();
+			delete objDecl;
+			return newDecl;
 		} else if ( objDecl->get_isInline() || objDecl->get_isNoreturn() ) {
 			throw SemanticError( "invalid inline or _Noreturn specification in declaration of ", objDecl );
Index: src/SynTree/AggregateDecl.cc
===================================================================
--- src/SynTree/AggregateDecl.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/SynTree/AggregateDecl.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -69,5 +69,5 @@
 std::string EnumDecl::typeString() const { return "enum"; }
 
-std::string TraitDecl::typeString() const { return "context"; }
+std::string TraitDecl::typeString() const { return "trait"; }
 
 // Local Variables: //
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/SynTree/ReferenceToType.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -64,4 +64,6 @@
 }
 
+bool StructInstType::isComplete() const { return baseStruct->has_body(); }
+
 void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
 	assert( baseStruct );
@@ -90,4 +92,6 @@
 }
 
+bool UnionInstType::isComplete() const { return baseUnion->has_body(); }
+
 void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
 	assert( baseUnion );
@@ -111,5 +115,5 @@
 std::string EnumInstType::typeString() const { return "enum"; }
 
-std::string TraitInstType::typeString() const { return "context"; }
+std::string TraitInstType::typeString() const { return "trait"; }
 
 TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ) {
@@ -120,4 +124,6 @@
 	deleteAll( members );
 }
+
+bool TraitInstType::isComplete() const { assert( false ); }
 
 TypeInstType::TypeInstType( const Type::Qualifiers &tq, const std::string &name, TypeDecl *baseType ) : Parent( tq, name ) {
@@ -143,4 +149,6 @@
 std::string TypeInstType::typeString() const { return "type"; }
 
+bool TypeInstType::isComplete() const { return baseType->isComplete(); }
+
 void TypeInstType::print( std::ostream &os, int indent ) const {
 	using std::endl;
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/SynTree/Type.h	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -74,4 +74,6 @@
 	virtual Type * getComponent( unsigned i ) { assertf( size() == 1 && i == 0, "Type::getComponent was called with size %d and index %d\n", size(), i ); return this; }
 
+	virtual bool isComplete() const { return true; }
+
 	virtual Type *clone() const = 0;
 	virtual void accept( Visitor &v ) = 0;
@@ -90,4 +92,5 @@
 
 	virtual unsigned size() const { return 0; };
+	virtual bool isComplete() const { return false; }
 
 	virtual VoidType *clone() const { return new VoidType( *this ); }
@@ -185,4 +188,6 @@
 	void set_isStatic( bool newValue ) { isStatic = newValue; }
 
+	virtual bool isComplete() const { return ! isVarLen; }
+
 	virtual ArrayType *clone() const { return new ArrayType( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -258,4 +263,6 @@
 	std::list<TypeDecl*> * get_baseParameters();
 
+	virtual bool isComplete() const;
+
 	/// Looks up the members of this struct named "name" and places them into "foundDecls".
 	/// Clones declarations into "foundDecls", caller responsible for freeing
@@ -287,4 +294,6 @@
 	std::list<TypeDecl*> * get_baseParameters();
 
+	virtual bool isComplete() const;
+
 	/// looks up the members of this union named "name" and places them into "foundDecls"
 	/// Clones declarations into "foundDecls", caller responsible for freeing
@@ -310,4 +319,7 @@
 	EnumInstType( const EnumInstType &other ) : Parent( other ) {}
 
+	// xxx - enum inst does not currently contain a pointer to base, this should be fixed.
+	// virtual bool isComplete() const { return baseEnum()->hasBody(); }
+
 	virtual EnumInstType *clone() const { return new EnumInstType( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -325,4 +337,6 @@
 
 	std::list< Declaration* >& get_members() { return members; }
+
+	virtual bool isComplete() const;
 
 	virtual TraitInstType *clone() const { return new TraitInstType( *this ); }
@@ -349,4 +363,6 @@
 	bool get_isFtype() const { return isFtype; }
 	void set_isFtype( bool newValue ) { isFtype = newValue; }
+
+	virtual bool isComplete() const;
 
 	virtual TypeInstType *clone() const { return new TypeInstType( *this ); }
@@ -382,4 +398,6 @@
 	}
 
+	// virtual bool isComplete() const { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
+
 	virtual TupleType *clone() const { return new TupleType( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -398,4 +416,6 @@
 	Expression *get_expr() const { return expr; }
 	void set_expr( Expression *newValue ) { expr = newValue; }
+
+	virtual bool isComplete() const { assert( false ); return false; }
 
 	virtual TypeofType *clone() const { return new TypeofType( *this ); }
@@ -423,4 +443,6 @@
 	void set_isType( bool newValue ) { isType = newValue; }
 
+	virtual bool isComplete() const { assert( false ); } // xxx - not sure what to do here
+
 	virtual AttrType *clone() const { return new AttrType( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -439,4 +461,6 @@
 	VarArgsType();
 	VarArgsType( Type::Qualifiers tq );
+
+	virtual bool isComplete() const{ return true; } // xxx - is this right?
 
 	virtual VarArgsType *clone() const { return new VarArgsType( *this ); }
Index: src/driver/cfa.cc
===================================================================
--- src/driver/cfa.cc	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/driver/cfa.cc	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -267,4 +267,6 @@
 		}
 		nargs += 1;
+		args[nargs] = "-lpthread";
+		nargs += 1;
 	} // if
 #endif //HAVE_LIBCFA
Index: src/examples/thread.c
===================================================================
--- src/examples/thread.c	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/examples/thread.c	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -1,2 +1,3 @@
+#include <fstream>
 #include <kernel>
 #include <stdlib>
@@ -4,24 +5,13 @@
 
 // Start coroutine routines
-extern "C" {
-      forall(dtype T | is_coroutine(T))
-      void CtxInvokeCoroutine(T * this);
-
-      forall(dtype T | is_coroutine(T))
-      void CtxStart(T * this, void ( *invoke)(T *));
-
-	forall(dtype T | is_coroutine(T))
-      void CtxInvokeThread(T * this);
-}
-
 struct MyThread {
-	thread_h t;
+	thread t;
 	unsigned id;
 	unsigned count;
 };
 
+DECL_THREAD(MyThread)
+
 void ?{}( MyThread * this ) {
-	this->id = 0;
-	this->count = 10;
 }
 
@@ -31,37 +21,34 @@
 }
 
-void ^?{}( MyThread * this ) {}
-
 void main(MyThread* this) {
-	printf("Main called with %p\n", this);
-	printf("Thread %d : Suspending %d times\n", this->id, this->count);
+	sout | "Thread" | this->id | " : Suspending" | this->count | "times" | endl;
+	yield();
 
 	for(int i = 0; i < this->count; i++) {
-		printf("Thread %d : Suspend No. %d\n", this->id, i + 1);
-		printf("Back to %p\n", &this->t.c);
-		suspend();
+		sout | "Thread" | this->id | " : Suspend No." | i + 1 | endl;
+		yield();
 	}
 }
 
-thread_h* get_thread(MyThread* this) {
-	return &this->t;
-}
+int main(int argc, char* argv[]) {
 
-coroutine* get_coroutine(MyThread* this) {
-	return &this->t.c;
-}
+	unsigned itterations = 10u;
+	if(argc == 2) { 
+		int val = ato(argv[1]);
+		assert(val >= 0);
+		itterations = val;
+	}
 
-int main() {
+	sout | "User main begin" | endl;
 
-	thread(MyThread) thread1;
-	thread(MyThread) thread2;
+	{
+		processor p;
+		{
+			scoped(MyThread) thread1 = { 1u, itterations };
+			scoped(MyThread) thread2 = { 2u, itterations };
+		}
+	}
 
-	thread2.handle.id = 1;
-
-	printf("\n\nMain is %p\n", this_coroutine());
-
-	kernel_run();
-
-	printf("Kernel terminated correctly\n");
+	sout | "User main end" | endl;
 
 	return 0;
Index: src/libcfa/concurrency/CtxSwitch-i386.S
===================================================================
--- src/libcfa/concurrency/CtxSwitch-i386.S	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/libcfa/concurrency/CtxSwitch-i386.S	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -86,4 +86,13 @@
 	ret
 
+.text
+	.align 2
+.globl	CtxGet
+CtxGet:
+	movl %esp,SP_OFFSET(%eax)
+	movl %ebp,FP_OFFSET(%eax)
+
+	ret
+
 // Local Variables: //
 // compile-command: "make install" //
Index: src/libcfa/concurrency/CtxSwitch-x86_64.S
===================================================================
--- src/libcfa/concurrency/CtxSwitch-x86_64.S	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/libcfa/concurrency/CtxSwitch-x86_64.S	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -84,4 +84,13 @@
 	jmp *%r12
 
+.text
+	.align 2
+.globl	CtxGet
+CtxGet:
+	movq %rsp,SP_OFFSET(%rdi)
+	movq %rbp,FP_OFFSET(%rdi)
+
+	ret
+
 // Local Variables: //
 // mode: c //
Index: src/libcfa/concurrency/coroutines
===================================================================
--- src/libcfa/concurrency/coroutines	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/libcfa/concurrency/coroutines	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -62,8 +62,5 @@
 
 // Get current coroutine
-extern coroutine * current_coroutine; //PRIVATE, never use directly
-static inline coroutine * this_coroutine(void) {
-	return current_coroutine;
-}
+coroutine * this_coroutine(void);
 
 // Private wrappers for context switch and stack creation
@@ -76,9 +73,9 @@
 
 	assertf( src->last != 0,
-		"Attempt to suspend coroutine %.256s (%p) that has never been resumed.\n"
+		"Attempt to suspend coroutine \"%.256s\" (%p) that has never been resumed.\n"
 		"Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",
 		src->name, src );
 	assertf( src->last->notHalted,
-		"Attempt by coroutine %.256s (%p) to suspend back to terminated coroutine %.256s (%p).\n"
+		"Attempt by coroutine \"%.256s\" (%p) to suspend back to terminated coroutine \"%.256s\" (%p).\n"
 		"Possible cause is terminated coroutine's main routine has already returned.",
 		src->name, src, src->last->name, src->last );
Index: src/libcfa/concurrency/coroutines.c
===================================================================
--- src/libcfa/concurrency/coroutines.c	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/libcfa/concurrency/coroutines.c	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -1,2 +1,3 @@
+//                              -*- Mode: CFA -*-
 //
 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
@@ -14,4 +15,6 @@
 //
 
+#include "coroutines"
+
 extern "C" {
 #include <stddef.h>
@@ -23,9 +26,11 @@
 }
 
-#include "coroutines"
+#include "kernel"
 #include "libhdr.h"
 
 #define __CFA_INVOKE_PRIVATE__
 #include "invoke.h"
+
+extern processor * get_this_processor();
 
 //-----------------------------------------------------------------------------
@@ -35,19 +40,4 @@
 #define MinStackSize 1000
 static size_t pageSize = 0;				// architecture pagesize HACK, should go in proper runtime singleton
-
-//Extra private desctructor for the main
-//FIXME the main should not actually allocate a stack
-//Since the main is never resumed the extra stack does not cause 
-//any problem but it is wasted memory
-void ?{}(coStack_t* this, size_t size);
-void ?{}(coroutine* this, size_t size);
-
-//Main coroutine
-//FIXME do not construct a stack for the main
-coroutine main_coroutine = { 1000 };
-
-//Current coroutine
-//Will need to be in TLS when multi-threading is added
-coroutine* current_coroutine = &main_coroutine;
 
 //-----------------------------------------------------------------------------
@@ -111,6 +101,4 @@
 // is not inline (We can't inline Cforall in C)
 void suspend_no_inline(void) {
-	LIB_DEBUG_PRINTF("Suspending back : to %p from %p\n", this_coroutine(), this_coroutine() ? this_coroutine()->last : (void*)-1);
-
 	suspend();
 }
@@ -123,5 +111,5 @@
 
 	// set new coroutine that task is executing
-	current_coroutine = dst;			
+	get_this_processor()->current_coroutine = dst;			
 
 	// context switch to specified coroutine
Index: src/libcfa/concurrency/invoke.c
===================================================================
--- src/libcfa/concurrency/invoke.c	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/libcfa/concurrency/invoke.c	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -1,2 +1,17 @@
+//                              -*- Mode: C -*-
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// invoke.c --
+//
+// Author           : Thierry Delisle
+// Created On       : Tue Jan 17 12:27:26 2016
+// Last Modified By : Thierry Delisle
+// Last Modified On : --
+// Update Count     : 0
+//
 
 #include <stdbool.h>
@@ -14,5 +29,5 @@
 
 extern void __suspend_no_inline__F___1(void);
-extern void __scheduler_remove__F_P9sthread_h__1(struct thread_h*);
+extern void __signal_termination__F_P7sthread__1(struct thread*);
 
 void CtxInvokeCoroutine(
@@ -33,4 +48,7 @@
       main( this );
 
+      cor->state = Halt;
+      cor->notHalted = false;
+
       //Final suspend, should never return
       __suspend_no_inline__F___1();
@@ -40,5 +58,5 @@
 void CtxInvokeThread(
       void (*main)(void *), 
-      struct thread_h *(*get_thread)(void *), 
+      struct thread *(*get_thread)(void *), 
       void *this
 ) {
@@ -47,5 +65,5 @@
       __suspend_no_inline__F___1();
 
-      struct thread_h* thrd = get_thread( this );
+      struct thread* thrd = get_thread( this );
       struct coroutine* cor = &thrd->c;
       cor->state = Active;
@@ -54,5 +72,5 @@
       main( this );
 
-      __scheduler_remove__F_P9sthread_h__1(thrd);
+      __signal_termination__F_P7sthread__1(thrd);
 
       //Final suspend, should never return
Index: src/libcfa/concurrency/invoke.h
===================================================================
--- src/libcfa/concurrency/invoke.h	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/libcfa/concurrency/invoke.h	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -1,2 +1,18 @@
+//                              -*- Mode: C -*-
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// invoke.h --
+//
+// Author           : Thierry Delisle
+// Created On       : Tue Jan 17 12:27:26 2016
+// Last Modified By : Thierry Delisle
+// Last Modified On : --
+// Update Count     : 0
+//
+
 #include <stdbool.h>
 #include <stdint.h>
@@ -11,4 +27,19 @@
 
       #define unlikely(x)    __builtin_expect(!!(x), 0)
+      #define thread_local _Thread_local
+      #define SCHEDULER_CAPACITY 10
+
+      struct simple_thread_list {
+            struct thread * head;
+            struct thread ** tail;
+      };
+
+      #ifdef __CFORALL__
+      extern "Cforall" {
+            void ?{}( struct simple_thread_list * );
+            void append( struct simple_thread_list *, struct thread * );
+            struct thread * pop_head( struct simple_thread_list * );
+      }
+      #endif
 
       struct coStack_t {
@@ -35,6 +66,12 @@
       };
 
-      struct thread_h {
+      struct simple_lock {
+      	struct simple_thread_list blocked;
+      };
+
+      struct thread {
             struct coroutine c;
+            struct simple_lock lock;
+            struct thread * next;
       };
 
@@ -52,5 +89,6 @@
       // assembler routines that performs the context switch
       extern void CtxInvokeStub( void );
-      void CtxSwitch( void *from, void *to ) asm ("CtxSwitch");
+      void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
+      void CtxGet( void * this ) asm ("CtxGet");
 
 #endif //_INVOKE_PRIVATE_H_
Index: src/libcfa/concurrency/kernel
===================================================================
--- src/libcfa/concurrency/kernel	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/libcfa/concurrency/kernel	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -20,18 +20,82 @@
 #include <stdbool.h>
 
+#include "invoke.h"
+
+extern "C" {
+#include <pthread.h>
+}
+
+//-----------------------------------------------------------------------------
+// Cluster
+struct cluster {
+	simple_thread_list ready_queue;
+	pthread_spinlock_t lock;
+};
+
+void ?{}(cluster * this);
+void ^?{}(cluster * this);
+
+//-----------------------------------------------------------------------------
+// Processor
 struct processor {
-	struct proc_coroutine * cor;
-	unsigned int thread_index;
-	unsigned int thread_count;
-	struct thread_h * threads[10];
-	bool terminated;
+	struct processorCtx_t * ctx;
+	cluster * cltr;
+	coroutine * current_coroutine;
+	thread * current_thread;
+	pthread_t kernel_thread;
+	simple_lock lock;
+	volatile bool terminated;
 };
 
 void ?{}(processor * this);
+void ?{}(processor * this, cluster * cltr);
 void ^?{}(processor * this);
 
-void scheduler_add( struct thread_h * thrd );
-void scheduler_remove( struct thread_h * thrd );
-void kernel_run( void );
+
+//-----------------------------------------------------------------------------
+// Locks
+
+void ?{}(simple_lock * this);
+void ^?{}(simple_lock * this);
+
+void lock( simple_lock * );
+void unlock( simple_lock * );
+
+struct pthread_spinlock_guard {
+	pthread_spinlock_t * lock;
+};
+
+static inline void ?{}( pthread_spinlock_guard * this, pthread_spinlock_t * lock ) {
+	this->lock = lock;
+	pthread_spin_lock( this->lock );
+}
+
+static inline void ^?{}( pthread_spinlock_guard * this ) {
+	pthread_spin_unlock( this->lock );
+}
+
+// //Simple spinlock implementation from 
+// //http://stackoverflow.com/questions/1383363/is-my-spin-lock-implementation-correct-and-optimal
+// //Not optimal but correct
+// #define VOL 
+
+// struct simple_spinlock {
+// 	VOL int lock;
+// };
+
+// extern VOL int __sync_lock_test_and_set( VOL int *, VOL int);
+// extern void __sync_synchronize();
+
+// static inline void lock( simple_spinlock * this ) {
+//     while (__sync_lock_test_and_set(&this->lock, 1)) {
+//         // Do nothing. This GCC builtin instruction
+//         // ensures memory barrier.
+//     }
+// }
+
+// static inline void unlock( simple_spinlock * this ) {
+//     __sync_synchronize(); // Memory barrier.
+//     this->lock = 0;
+// }
 
 #endif //KERNEL_H
Index: src/libcfa/concurrency/kernel.c
===================================================================
--- src/libcfa/concurrency/kernel.c	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/libcfa/concurrency/kernel.c	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -20,4 +20,7 @@
 //C Includes
 #include <stddef.h>
+extern "C" {
+#include <sys/resource.h>
+}
 
 //CFA Includes
@@ -29,67 +32,167 @@
 #include "invoke.h"
 
-processor systemProcessorStorage = {};
-processor * systemProcessor = &systemProcessorStorage;
-
-void ?{}(processor * this) {
-	this->cor = NULL;
-	this->thread_index = 0;
-	this->thread_count = 10;
-	this->terminated = false;
-
-	for(int i = 0; i < 10; i++) {
-		this->threads[i] = NULL;
-	}
-
-	LIB_DEBUG_PRINTF("Processor : ctor for core %p (core spots %d)\n", this, this->thread_count);
-}
-
-void ^?{}(processor * this) {
-
-}
-
-//-----------------------------------------------------------------------------
-// Processor coroutine
-struct proc_coroutine {
+//-----------------------------------------------------------------------------
+// Kernel storage
+struct processorCtx_t {
 	processor * proc;
 	coroutine c;
 };
 
-void ?{}(coroutine * this, processor * proc) {
-	this{};
-}
-
-DECL_COROUTINE(proc_coroutine)
-
-void ?{}(proc_coroutine * this, processor * proc) {
-	(&this->c){proc};
+DECL_COROUTINE(processorCtx_t)
+
+#define KERNEL_STORAGE(T,X) static char X##_storage[sizeof(T)]
+
+KERNEL_STORAGE(processorCtx_t, systemProcessorCtx);
+KERNEL_STORAGE(cluster, systemCluster);
+KERNEL_STORAGE(processor, systemProcessor);
+KERNEL_STORAGE(thread, mainThread);
+KERNEL_STORAGE(machine_context_t, mainThread_context);
+
+cluster * systemCluster;
+processor * systemProcessor;
+thread * mainThread;
+
+void kernel_startup(void)  __attribute__((constructor(101)));
+void kernel_shutdown(void) __attribute__((destructor(101)));
+
+//-----------------------------------------------------------------------------
+// Global state
+
+thread_local processor * this_processor;
+
+processor * get_this_processor() {
+	return this_processor;
+}
+
+coroutine * this_coroutine(void) {
+	return this_processor->current_coroutine;
+}
+
+thread * this_thread(void) {
+	return this_processor->current_thread;
+}
+
+//-----------------------------------------------------------------------------
+// Main thread construction
+struct current_stack_info_t {
+	machine_context_t ctx;	
+	unsigned int size;		// size of stack
+	void *base;				// base of stack
+	void *storage;			// pointer to stack
+	void *limit;			// stack grows towards stack limit
+	void *context;			// address of cfa_context_t
+	void *top;				// address of top of storage
+};
+
+void ?{}( current_stack_info_t * this ) {
+	CtxGet( &this->ctx );
+	this->base = this->ctx.FP;
+	this->storage = this->ctx.SP;
+
+	rlimit r;
+	int ret = getrlimit( RLIMIT_STACK, &r);
+	this->size = r.rlim_cur;
+
+	this->limit = (void *)(((intptr_t)this->base) - this->size);
+	this->context = &mainThread_context_storage;
+	this->top = this->base;
+}
+
+void ?{}( coStack_t * this, current_stack_info_t * info) {
+	this->size = info->size;
+	this->storage = info->storage;
+	this->limit = info->limit;
+	this->base = info->base;
+	this->context = info->context;
+	this->top = info->top;
+	this->userStack = true;
+}
+
+void ?{}( coroutine * this, current_stack_info_t * info) {
+	(&this->stack){ info };	
+	this->name = "Main Thread";
+	this->errno_ = 0;
+	this->state = Inactive;
+	this->notHalted = true;
+}
+
+void ?{}( thread * this, current_stack_info_t * info) {
+	(&this->c){ info };
+}
+
+//-----------------------------------------------------------------------------
+// Processor coroutine
+void ?{}(processorCtx_t * this, processor * proc) {
+	(&this->c){};
 	this->proc = proc;
-	proc->cor = this;
-}
-
-void ^?{}(proc_coroutine * this) {
-	^(&this->c){};
-}
-
-void CtxInvokeProcessor(processor * proc) {
-	proc_coroutine proc_cor_storage = {proc};
-	resume( &proc_cor_storage );
+	proc->ctx = this;
+}
+
+void ?{}(processorCtx_t * this, processor * proc, current_stack_info_t * info) {
+	(&this->c){ info };
+	this->proc = proc;
+	proc->ctx = this;
+}
+
+void start(processor * this);
+
+void ?{}(processor * this) {
+	this{ systemCluster };
+}
+
+void ?{}(processor * this, cluster * cltr) {
+	this->cltr = cltr;
+	this->current_coroutine = NULL;
+	this->current_thread = NULL;
+	(&this->lock){};
+	this->terminated = false;
+
+	start( this );
+}
+
+void ?{}(processor * this, cluster * cltr, processorCtx_t * ctx) {
+	this->cltr = cltr;
+	this->current_coroutine = NULL;
+	this->current_thread = NULL;
+	(&this->lock){};
+	this->terminated = false;
+
+	this->ctx = ctx;
+	LIB_DEBUG_PRINTF("Kernel : constructing processor context %p\n", ctx);
+	ctx{ this };
+}
+
+void ^?{}(processor * this) {
+	if( ! this->terminated ) {
+		LIB_DEBUG_PRINTF("Kernel : core %p signaling termination\n", this);
+		this->terminated = true;
+		lock( &this->lock );
+	}
+}
+
+void ?{}(cluster * this) {
+	( &this->ready_queue ){};
+	pthread_spin_init( &this->lock, PTHREAD_PROCESS_PRIVATE );
+}
+
+void ^?{}(cluster * this) {
+	pthread_spin_destroy( &this->lock );
 }
 
 //-----------------------------------------------------------------------------
 // Processor running routines
-void main(proc_coroutine * cor);
-thread_h * nextThread(processor * this);
-void runThread(processor * this, thread_h * dst);
+void main(processorCtx_t * ctx);
+thread * nextThread(cluster * this);
+void runThread(processor * this, thread * dst);
 void spin(processor * this, unsigned int * spin_count);
 
-void main(proc_coroutine * cor) {
-	processor * this;
-	this = cor->proc;
-
-	thread_h * readyThread = NULL;
+void main(processorCtx_t * ctx) {
+	processor * this = ctx->proc;
+	LIB_DEBUG_PRINTF("Kernel : core %p starting\n", this);
+
+	thread * readyThread = NULL;
 	for( unsigned int spin_count = 0; ! this->terminated; spin_count++ ) {
 		
-		readyThread = nextThread(this);
+		readyThread = nextThread( this->cltr );
 
 		if(readyThread) {
@@ -101,20 +204,11 @@
 	}
 
+	LIB_DEBUG_PRINTF("Kernel : core %p unlocking thread\n", this);
+	unlock( &this->lock );
 	LIB_DEBUG_PRINTF("Kernel : core %p terminated\n", this);
 }
 
-thread_h * nextThread(processor * this) {
-	for(int i = 0; i < this->thread_count; i++) {
-		this->thread_index = (this->thread_index + 1) % this->thread_count;	
-		
-		thread_h * thrd = this->threads[this->thread_index];
-		if(thrd) return thrd;
-	}
-
-	return NULL;
-}
-
-void runThread(processor * this, thread_h * dst) {
-	coroutine * proc_ctx = get_coroutine(this->cor);
+void runThread(processor * this, thread * dst) {
+	coroutine * proc_ctx = get_coroutine(this->ctx);
 	coroutine * thrd_ctx = get_coroutine(dst);
 	thrd_ctx->last = proc_ctx;
@@ -122,9 +216,10 @@
 	// context switch to specified coroutine
 	// Which is now the current_coroutine
-	LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);
-	current_coroutine = thrd_ctx;
+	// LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);
+	this->current_thread = dst;
+	this->current_coroutine = thrd_ctx;
 	CtxSwitch( proc_ctx->stack.context, thrd_ctx->stack.context );
-	current_coroutine = proc_ctx;
-	LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);
+	this->current_coroutine = proc_ctx;
+	// LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);
 
 	// when CtxSwitch returns we are back in the processor coroutine
@@ -135,39 +230,196 @@
 }
 
-//-----------------------------------------------------------------------------
-// Kernel runner (Temporary)
-
-void scheduler_add( struct thread_h * thrd ) {
-	LIB_DEBUG_PRINTF("Kernel : scheduling %p on core %p (%d spots)\n", thrd, systemProcessor, systemProcessor->thread_count);
-	for(int i = 0; i < systemProcessor->thread_count; i++) {
-		if(systemProcessor->threads[i] == NULL) {
-			systemProcessor->threads[i] = thrd;
-			return;
+void * CtxInvokeProcessor(void * arg) {
+	processor * proc = (processor *) arg;
+	this_processor = proc;
+	// SKULLDUGGERY: We want to create a context for the processor coroutine
+	// which is needed for the 2-step context switch. However, there is no reason
+	// to waste the perfectly valid stack create by pthread. 
+	current_stack_info_t info;
+	machine_context_t ctx;
+	info.context = &ctx;
+	processorCtx_t proc_cor_storage = { proc, &info };
+
+	proc->current_coroutine = &proc->ctx->c;
+	proc->current_thread = NULL;
+
+	LIB_DEBUG_PRINTF("Kernel : core %p created (%p)\n", proc, proc->ctx);
+
+	// LIB_DEBUG_PRINTF("Kernel : core    base : %p \n", info.base );
+	// LIB_DEBUG_PRINTF("Kernel : core storage : %p \n", info.storage );
+	// LIB_DEBUG_PRINTF("Kernel : core    size : %x \n", info.size );
+	// LIB_DEBUG_PRINTF("Kernel : core   limit : %p \n", info.limit );
+	// LIB_DEBUG_PRINTF("Kernel : core context : %p \n", info.context );
+	// LIB_DEBUG_PRINTF("Kernel : core     top : %p \n", info.top );
+
+	//We now have a proper context from which to schedule threads
+
+	// SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't 
+	// resume it to start it like it normally would, it will just context switch 
+	// back to here. Instead directly call the main since we already are on the 
+	// appropriate stack.
+	proc_cor_storage.c.state = Active;
+      main( &proc_cor_storage );
+      proc_cor_storage.c.state = Halt;
+      proc_cor_storage.c.notHalted = false;
+
+	LIB_DEBUG_PRINTF("Kernel : core %p main ended (%p)\n", proc, proc->ctx);	
+
+	return NULL;
+}
+
+void start(processor * this) {
+	LIB_DEBUG_PRINTF("Kernel : Starting core %p\n", this);
+	
+	pthread_attr_t attributes;
+	pthread_attr_init( &attributes );
+
+	pthread_create( &this->kernel_thread, &attributes, CtxInvokeProcessor, (void*)this );
+
+	pthread_attr_destroy( &attributes );
+
+	LIB_DEBUG_PRINTF("Kernel : core %p started\n", this);	
+}
+
+//-----------------------------------------------------------------------------
+// Scheduler routines
+void thread_schedule( thread * thrd ) {
+	assertf( thrd->next == NULL, "Expected null got %p", thrd->next );
+	
+	pthread_spinlock_guard guard = { &systemProcessor->cltr->lock };
+	append( &systemProcessor->cltr->ready_queue, thrd );
+}
+
+thread * nextThread(cluster * this) {
+	pthread_spinlock_guard guard = { &this->lock };
+	return pop_head( &this->ready_queue );
+}
+
+//-----------------------------------------------------------------------------
+// Kernel boot procedures
+void kernel_startup(void) {
+
+	// SKULLDUGGERY: the mainThread steals the process main thread 
+	// which will then be scheduled by the systemProcessor normally
+	LIB_DEBUG_PRINTF("Kernel : Starting\n");	
+
+	current_stack_info_t info;
+
+	// LIB_DEBUG_PRINTF("Kernel : core    base : %p \n", info.base );
+	// LIB_DEBUG_PRINTF("Kernel : core storage : %p \n", info.storage );
+	// LIB_DEBUG_PRINTF("Kernel : core    size : %x \n", info.size );
+	// LIB_DEBUG_PRINTF("Kernel : core   limit : %p \n", info.limit );
+	// LIB_DEBUG_PRINTF("Kernel : core context : %p \n", info.context );
+	// LIB_DEBUG_PRINTF("Kernel : core     top : %p \n", info.top );
+
+	// Start by initializing the main thread
+	mainThread = (thread *)&mainThread_storage;
+	mainThread{ &info };
+
+	// Initialize the system cluster
+	systemCluster = (cluster *)&systemCluster_storage;
+	systemCluster{};
+
+	// Initialize the system processor and the system processor ctx
+	// (the coroutine that contains the processing control flow)
+	systemProcessor = (processor *)&systemProcessor_storage;
+	systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtx_storage };
+
+	// Add the main thread to the ready queue 
+	// once resume is called on systemProcessor->ctx the mainThread needs to be scheduled like any normal thread
+	thread_schedule(mainThread);
+
+	//initialize the global state variables
+	this_processor = systemProcessor;
+	this_processor->current_thread = mainThread;
+	this_processor->current_coroutine = &mainThread->c;
+
+	// SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX
+	// context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
+	// mainThread is on the ready queue when this call is made. 
+	resume(systemProcessor->ctx);
+
+
+
+	// THE SYSTEM IS NOW COMPLETELY RUNNING
+
+
+
+	LIB_DEBUG_PRINTF("Kernel : Started\n--------------------------------------------------\n\n");
+}
+
+void kernel_shutdown(void) {
+	LIB_DEBUG_PRINTF("\n--------------------------------------------------\nKernel : Shutting down\n");
+
+	// SKULLDUGGERY: Notify the systemProcessor it needs to terminates.
+	// When its coroutine terminates, it return control to the mainThread
+	// which is currently here
+	systemProcessor->terminated = true;
+	suspend();
+
+	// THE SYSTEM IS NOW COMPLETELY STOPPED
+
+	// Destroy the system processor and its context in reverse order of construction
+	// These were manually constructed so we need manually destroy them
+	^(systemProcessor->ctx){};
+	^(systemProcessor){};
+
+	// Final step, destroy the main thread since it is no longer needed
+	// Since we provided a stack to this taxk it will not destroy anything
+	^(mainThread){};
+
+	LIB_DEBUG_PRINTF("Kernel : Shutdown complete\n");	
+}
+
+//-----------------------------------------------------------------------------
+// Locks
+void ?{}( simple_lock * this ) {
+	( &this->blocked ){};
+}
+
+void ^?{}( simple_lock * this ) {
+
+}
+
+void lock( simple_lock * this ) {
+	{
+		pthread_spinlock_guard guard = { &systemCluster->lock };  	//HUGE TEMP HACK which only works if we have a single cluster and is stupid
+		append( &this->blocked, this_thread() );
+	}
+	suspend();
+}
+
+void unlock( simple_lock * this ) {
+	thread * it;
+	while( it = pop_head( &this->blocked) ) {
+		thread_schedule( it );
+	}
+}
+
+//-----------------------------------------------------------------------------
+// Queues
+void ?{}( simple_thread_list * this ) {
+	this->head = NULL;
+	this->tail = &this->head;
+}
+
+void append( simple_thread_list * this, thread * t ) {
+	assert( t->next == NULL );
+	*this->tail = t;
+	this->tail = &t->next;
+}
+
+thread * pop_head( simple_thread_list * this ) {
+	thread * head = this->head;
+	if( head ) {
+		this->head = head->next;
+		if( !head->next ) {
+			this->tail = &this->head;
 		}
-	}
-	assert(false);
-}
-
-void scheduler_remove( struct thread_h * thrd ) {
-	LIB_DEBUG_PRINTF("Kernel : unscheduling %p from core %p\n", thrd, systemProcessor);
-	for(int i = 0; i < systemProcessor->thread_count; i++) {
-		if(systemProcessor->threads[i] == thrd) {
-			systemProcessor->threads[i] = NULL;
-			break;
-		}
-	}
-	for(int i = 0; i < systemProcessor->thread_count; i++) {
-		if(systemProcessor->threads[i] != NULL) {
-			return;
-		}
-	}
-	LIB_DEBUG_PRINTF("Kernel : terminating core %p\n\n\n", systemProcessor);	
-	systemProcessor->terminated = true;
-}
-
-void kernel_run( void ) {
-	CtxInvokeProcessor(systemProcessor);
-}
-
+		head->next = NULL;
+	}	
+	
+	return head;
+}
 // Local Variables: //
 // mode: c //
Index: src/libcfa/concurrency/threads
===================================================================
--- src/libcfa/concurrency/threads	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/libcfa/concurrency/threads	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -27,44 +27,45 @@
 // Anything that implements this trait can be resumed.
 // Anything that is resumed is a coroutine.
-trait is_thread(dtype T /*| sized(T)*/) {
+trait is_thread(dtype T | sized(T)) {
       void main(T* this);
-      thread_h* get_thread(T* this);
-	/*void ?{}(T*);
-	void ^?{}(T*);*/
+      thread* get_thread(T* this);
 };
 
-forall(otype T | is_thread(T) )
+#define DECL_THREAD(X) static inline thread* get_thread(X* this) { return &this->t; } void main(X* this);
+
+forall( dtype T | sized(T) | is_thread(T) )
 static inline coroutine* get_coroutine(T* this) {
 	return &get_thread(this)->c;
 }
 
-static inline coroutine* get_coroutine(thread_h* this) {
+static inline coroutine* get_coroutine(thread* this) {
 	return &this->c;
 }
 
+thread * this_thread(void);
+
 //-----------------------------------------------------------------------------
 // Ctors and dtors
-void ?{}(thread_h* this);
-void ^?{}(thread_h* this);
+void ?{}(thread* this);
+void ^?{}(thread* this);
 
 //-----------------------------------------------------------------------------
 // thread runner
 // Structure that actually start and stop threads
-forall(otype T | is_thread(T) )
-struct thread {
+forall( dtype T | sized(T) | is_thread(T) )
+struct scoped {
 	T handle;
 };
 
-forall(otype T | is_thread(T) )
-void ?{}( thread(T)* this );
+forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T*); } )
+void ?{}( scoped(T)* this );
 
-forall(otype T, ttype P | is_thread(T) | { void ?{}(T*, P); } )
-void ?{}( thread(T)* this, P params );
+forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T*, P); } )
+void ?{}( scoped(T)* this, P params );
 
-forall(otype T | is_thread(T) )
-void ^?{}( thread(T)* this );
+forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } )
+void ^?{}( scoped(T)* this );
 
-//-----------------------------------------------------------------------------
-// PRIVATE exposed because of inline
+void yield();
 
 #endif //THREADS_H
Index: src/libcfa/concurrency/threads.c
===================================================================
--- src/libcfa/concurrency/threads.c	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/libcfa/concurrency/threads.c	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -23,41 +23,47 @@
 #include "invoke.h"
 
-#include <stdlib>
+extern "C" {
+	#include <stddef.h>
+}
+
+extern processor * get_this_processor();
 
 //-----------------------------------------------------------------------------
 // Forward declarations
-forall(otype T | is_thread(T) )
-void start( thread(T)* this );
+forall( dtype T | sized(T) | is_thread(T) )
+void start( T* this );
 
-forall(otype T | is_thread(T) )
-void stop( thread(T)* this );
+forall( dtype T | sized(T) | is_thread(T) )
+void stop( T* this );
 
 //-----------------------------------------------------------------------------
 // Thread ctors and dtors
 
-void ?{}(thread_h* this) {
+void ?{}(thread* this) {
 	(&this->c){};
+	this->c.name = "Anonymous Coroutine";
+	(&this->lock){};
+	this->next = NULL;
 }
 
-void ^?{}(thread_h* this) {
+void ^?{}(thread* this) {
 	^(&this->c){};
 }
 
-forall(otype T | is_thread(T) )
-void ?{}( thread(T)* this ) {
-	printf("thread() ctor\n");
+forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T*); } )
+void ?{}( scoped(T)* this ) {
 	(&this->handle){};
-	start(this);
+	start(&this->handle);
 }
 
-forall(otype T, ttype P | is_thread(T) | { void ?{}(T*, P); } )
-void ?{}( thread(T)* this, P params ) {
+forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T*, P); } )
+void ?{}( scoped(T)* this, P params ) {
 	(&this->handle){ params };
-	start(this);
+	start(&this->handle);
 }
 
-forall(otype T | is_thread(T) )
-void ^?{}( thread(T)* this ) {
-	stop(this);
+forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } )
+void ^?{}( scoped(T)* this ) {
+	stop(&this->handle);
 	^(&this->handle){};
 }
@@ -70,24 +76,39 @@
 }
 
-forall(otype T | is_thread(T))
-void start( thread(T)* this ) {
-	T* handle  = &this->handle;
-	coroutine* thrd_c = get_coroutine(handle);
-	thread_h*  thrd_h = get_thread   (handle);
+extern void thread_schedule( thread * );
+
+forall( dtype T | sized(T) | is_thread(T) )
+void start( T* this ) {
+	coroutine* thrd_c = get_coroutine(this);
+	thread*  thrd_h = get_thread   (this);
 	thrd_c->last = this_coroutine();
-	current_coroutine = thrd_c;
+	get_this_processor()->current_coroutine = thrd_c;
 
 	// LIB_DEBUG_PRINTF("Thread start : %p (t %p, c %p)\n", handle, thrd_c, thrd_h);
 
 	create_stack(&thrd_c->stack, thrd_c->stack.size);
-	CtxStart(handle, CtxInvokeThread);
+	CtxStart(this, CtxInvokeThread);
 	CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context );
 
-	scheduler_add(thrd_h);
+	thread_schedule(thrd_h);
 }
 
-forall(otype T | is_thread(T) )
-void stop( thread(T)* this ) {
+forall( dtype T | sized(T) | is_thread(T) )
+void stop( T* this ) {
+	thread*  thrd = get_thread(this);
+	if( thrd->c.notHalted ) {
+		lock( &thrd->lock );
+	}
+}
 
+void signal_termination( thread * this ) {
+	this->c.state = Halt;
+      this->c.notHalted = false;
+	unlock( &this->lock );
+}
+
+void yield( void ) {
+	thread_schedule( this_thread() );
+	suspend();
 }
 
Index: src/tests/.expect/32/declarationSpecifier.txt
===================================================================
--- src/tests/.expect/32/declarationSpecifier.txt	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/tests/.expect/32/declarationSpecifier.txt	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -1,7 +1,7 @@
-extern void *malloc(unsigned int __size);
-extern void free(void *__ptr);
-extern void abort(void);
-extern int atexit(void (*__func)(void));
-extern void exit(int __status);
+__attribute__ ((__malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);
+__attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
+__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void abort(void);
+__attribute__ ((__nonnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));
+__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void exit(int __status);
 extern int printf(const char *__restrict __format, ...);
 volatile const short __x1__CVs_1;
@@ -16,8 +16,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
 static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
 static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
+static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous0_1).__i__i_1)))) /* ?{} */);
@@ -40,8 +40,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
 static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1);
 static inline void ___constructor__F_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
 static inline void ___destructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1);
+static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
 static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous1_1).__i__i_1)))) /* ?{} */);
@@ -64,8 +64,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
 static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1);
 static inline void ___constructor__F_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
 static inline void ___destructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1);
+static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
 static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous2_1).__i__i_1)))) /* ?{} */);
@@ -88,8 +88,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
 static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1);
 static inline void ___constructor__F_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
 static inline void ___destructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1);
+static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
 static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous3_1).__i__i_1)))) /* ?{} */);
@@ -112,8 +112,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
 static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1);
 static inline void ___constructor__F_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
 static inline void ___destructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1);
+static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
 static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous4_1).__i__i_1)))) /* ?{} */);
@@ -136,8 +136,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
 static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1);
 static inline void ___constructor__F_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
 static inline void ___destructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1);
+static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
 static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous5_1).__i__i_1)))) /* ?{} */);
@@ -160,8 +160,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
 static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1);
 static inline void ___constructor__F_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
 static inline void ___destructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1);
+static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
 static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous6_1).__i__i_1)))) /* ?{} */);
@@ -184,8 +184,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
 static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1);
 static inline void ___constructor__F_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
 static inline void ___destructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1);
+static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
 static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous7_1).__i__i_1)))) /* ?{} */);
@@ -216,8 +216,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
 static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1);
 static inline void ___constructor__F_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
 static inline void ___destructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1);
+static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
 static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1){
     ((void)((*((short *)(&(*___dst__P13s__anonymous8_1).__i__s_1)))) /* ?{} */);
@@ -240,8 +240,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
 static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1);
 static inline void ___constructor__F_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
 static inline void ___destructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1);
+static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
 static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1){
     ((void)((*((short *)(&(*___dst__P13s__anonymous9_1).__i__s_1)))) /* ?{} */);
@@ -264,8 +264,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
 static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1);
 static inline void ___constructor__F_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
 static inline void ___destructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1);
+static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
 static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous10_1).__i__s_1)))) /* ?{} */);
@@ -288,8 +288,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
 static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1);
 static inline void ___constructor__F_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
 static inline void ___destructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1);
+static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
 static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous11_1).__i__s_1)))) /* ?{} */);
@@ -312,8 +312,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
 static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1);
 static inline void ___constructor__F_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
 static inline void ___destructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1);
+static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
 static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous12_1).__i__s_1)))) /* ?{} */);
@@ -336,8 +336,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
 static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1);
 static inline void ___constructor__F_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
 static inline void ___destructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1);
+static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
 static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous13_1).__i__s_1)))) /* ?{} */);
@@ -360,8 +360,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
 static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1);
 static inline void ___constructor__F_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
 static inline void ___destructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1);
+static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
 static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous14_1).__i__s_1)))) /* ?{} */);
@@ -384,8 +384,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
 static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1);
 static inline void ___constructor__F_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
 static inline void ___destructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1);
+static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
 static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous15_1).__i__s_1)))) /* ?{} */);
@@ -424,8 +424,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
 static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1);
 static inline void ___constructor__F_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
 static inline void ___destructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1);
+static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
 static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous16_1).__i__i_1)))) /* ?{} */);
@@ -448,8 +448,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
 static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1);
 static inline void ___constructor__F_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
 static inline void ___destructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1);
+static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
 static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous17_1).__i__i_1)))) /* ?{} */);
@@ -472,8 +472,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
 static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1);
 static inline void ___constructor__F_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
 static inline void ___destructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1);
+static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
 static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous18_1).__i__i_1)))) /* ?{} */);
@@ -496,8 +496,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
 static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1);
 static inline void ___constructor__F_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
 static inline void ___destructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1);
+static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
 static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous19_1).__i__i_1)))) /* ?{} */);
@@ -520,8 +520,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
 static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1);
 static inline void ___constructor__F_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
 static inline void ___destructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1);
+static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
 static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous20_1).__i__i_1)))) /* ?{} */);
@@ -544,8 +544,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
 static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1);
 static inline void ___constructor__F_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
 static inline void ___destructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1);
+static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
 static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous21_1).__i__i_1)))) /* ?{} */);
@@ -568,8 +568,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
 static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1);
 static inline void ___constructor__F_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
 static inline void ___destructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1);
+static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
 static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous22_1).__i__i_1)))) /* ?{} */);
@@ -592,8 +592,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
 static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1);
 static inline void ___constructor__F_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
 static inline void ___destructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1);
+static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
 static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous23_1).__i__i_1)))) /* ?{} */);
@@ -629,9 +629,9 @@
 }
 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); }
-extern void *malloc(unsigned int __size);
-extern void free(void *__ptr);
-extern void abort(void);
-extern int atexit(void (*__func)(void));
-extern void exit(int __status);
+__attribute__ ((__malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);
+__attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
+__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void abort(void);
+__attribute__ ((__nonnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));
+__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void exit(int __status);
 extern int printf(const char *__restrict __format, ...);
 static inline int invoke_main(int argc, char **argv, char **envp);
@@ -640,5 +640,5 @@
     int _tmp_cp_ret0;
     ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
-    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
     return ((int )___retval_main__i_1);
 }
Index: src/tests/.expect/32/extension.txt
===================================================================
--- src/tests/.expect/32/extension.txt	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/tests/.expect/32/extension.txt	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -1,7 +1,7 @@
-extern void *malloc(unsigned int __size);
-extern void free(void *__ptr);
-extern void abort(void);
-extern int atexit(void (*__func)(void));
-extern void exit(int __status);
+__attribute__ ((__malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);
+__attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
+__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void abort(void);
+__attribute__ ((__nonnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));
+__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void exit(int __status);
 extern int printf(const char *__restrict __format, ...);
 __extension__ int __a__i_1;
@@ -13,8 +13,8 @@
     __extension__ int __c__i_1;
 };
-static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
 static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1);
 static inline void ___constructor__F_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
 static inline void ___destructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1);
+static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
 static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1){
     ((void)((*((int *)(&(*___dst__P2sS_1).__a__i_1)))) /* ?{} */);
@@ -93,5 +93,5 @@
     int _tmp_cp_ret0;
     ((void)((_tmp_cp_ret0=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret0));
-    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
     ((void)__extension__ sizeof(3));
     ((void)__extension__ (((int )(3!=((int )0))) || ((int )(4!=((int )0)))));
Index: src/tests/.expect/32/gccExtensions.txt
===================================================================
--- src/tests/.expect/32/gccExtensions.txt	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/tests/.expect/32/gccExtensions.txt	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -1,7 +1,7 @@
-extern void *malloc(unsigned int __size);
-extern void free(void *__ptr);
-extern void abort(void);
-extern int atexit(void (*__func)(void));
-extern void exit(int __status);
+__attribute__ ((__malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);
+__attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
+__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void abort(void);
+__attribute__ ((__nonnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));
+__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void exit(int __status);
 extern int printf(const char *__restrict __format, ...);
 extern int __x__i_1 asm ( "xx" );
@@ -166,9 +166,9 @@
 }
 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); }
-extern void *malloc(unsigned int __size);
-extern void free(void *__ptr);
-extern void abort(void);
-extern int atexit(void (*__func)(void));
-extern void exit(int __status);
+__attribute__ ((__malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);
+__attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
+__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void abort(void);
+__attribute__ ((__nonnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));
+__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void exit(int __status);
 extern int printf(const char *__restrict __format, ...);
 static inline int invoke_main(int argc, char **argv, char **envp);
@@ -177,5 +177,5 @@
     int _tmp_cp_ret0;
     ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
-    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
     return ((int )___retval_main__i_1);
 }
Index: src/tests/.expect/64/declarationSpecifier.txt
===================================================================
--- src/tests/.expect/64/declarationSpecifier.txt	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/tests/.expect/64/declarationSpecifier.txt	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -16,8 +16,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
 static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
 static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
+static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous0_1).__i__i_1)))) /* ?{} */);
@@ -40,8 +40,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
 static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1);
 static inline void ___constructor__F_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
 static inline void ___destructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1);
+static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
 static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous1_1).__i__i_1)))) /* ?{} */);
@@ -64,8 +64,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
 static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1);
 static inline void ___constructor__F_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
 static inline void ___destructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1);
+static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
 static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous2_1).__i__i_1)))) /* ?{} */);
@@ -88,8 +88,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
 static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1);
 static inline void ___constructor__F_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
 static inline void ___destructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1);
+static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
 static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous3_1).__i__i_1)))) /* ?{} */);
@@ -112,8 +112,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
 static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1);
 static inline void ___constructor__F_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
 static inline void ___destructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1);
+static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
 static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous4_1).__i__i_1)))) /* ?{} */);
@@ -136,8 +136,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
 static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1);
 static inline void ___constructor__F_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
 static inline void ___destructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1);
+static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
 static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous5_1).__i__i_1)))) /* ?{} */);
@@ -160,8 +160,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
 static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1);
 static inline void ___constructor__F_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
 static inline void ___destructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1);
+static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
 static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous6_1).__i__i_1)))) /* ?{} */);
@@ -184,8 +184,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
 static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1);
 static inline void ___constructor__F_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
 static inline void ___destructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1);
+static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
 static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1){
     ((void)((*((int *)(&(*___dst__P13s__anonymous7_1).__i__i_1)))) /* ?{} */);
@@ -216,8 +216,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
 static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1);
 static inline void ___constructor__F_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
 static inline void ___destructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1);
+static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
 static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1){
     ((void)((*((short *)(&(*___dst__P13s__anonymous8_1).__i__s_1)))) /* ?{} */);
@@ -240,8 +240,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
 static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1);
 static inline void ___constructor__F_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
 static inline void ___destructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1);
+static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
 static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1){
     ((void)((*((short *)(&(*___dst__P13s__anonymous9_1).__i__s_1)))) /* ?{} */);
@@ -264,8 +264,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
 static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1);
 static inline void ___constructor__F_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
 static inline void ___destructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1);
+static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
 static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous10_1).__i__s_1)))) /* ?{} */);
@@ -288,8 +288,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
 static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1);
 static inline void ___constructor__F_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
 static inline void ___destructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1);
+static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
 static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous11_1).__i__s_1)))) /* ?{} */);
@@ -312,8 +312,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
 static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1);
 static inline void ___constructor__F_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
 static inline void ___destructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1);
+static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
 static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous12_1).__i__s_1)))) /* ?{} */);
@@ -336,8 +336,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
 static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1);
 static inline void ___constructor__F_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
 static inline void ___destructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1);
+static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
 static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous13_1).__i__s_1)))) /* ?{} */);
@@ -360,8 +360,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
 static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1);
 static inline void ___constructor__F_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
 static inline void ___destructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1);
+static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
 static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous14_1).__i__s_1)))) /* ?{} */);
@@ -384,8 +384,8 @@
     short __i__s_1;
 };
-static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
 static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1);
 static inline void ___constructor__F_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
 static inline void ___destructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1);
+static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
 static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1){
     ((void)((*((short *)(&(*___dst__P14s__anonymous15_1).__i__s_1)))) /* ?{} */);
@@ -424,8 +424,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
 static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1);
 static inline void ___constructor__F_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
 static inline void ___destructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1);
+static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
 static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous16_1).__i__i_1)))) /* ?{} */);
@@ -448,8 +448,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
 static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1);
 static inline void ___constructor__F_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
 static inline void ___destructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1);
+static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
 static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous17_1).__i__i_1)))) /* ?{} */);
@@ -472,8 +472,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
 static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1);
 static inline void ___constructor__F_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
 static inline void ___destructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1);
+static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
 static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous18_1).__i__i_1)))) /* ?{} */);
@@ -496,8 +496,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
 static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1);
 static inline void ___constructor__F_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
 static inline void ___destructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1);
+static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
 static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous19_1).__i__i_1)))) /* ?{} */);
@@ -520,8 +520,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
 static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1);
 static inline void ___constructor__F_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
 static inline void ___destructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1);
+static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
 static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous20_1).__i__i_1)))) /* ?{} */);
@@ -544,8 +544,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
 static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1);
 static inline void ___constructor__F_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
 static inline void ___destructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1);
+static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
 static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous21_1).__i__i_1)))) /* ?{} */);
@@ -568,8 +568,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
 static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1);
 static inline void ___constructor__F_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
 static inline void ___destructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1);
+static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
 static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous22_1).__i__i_1)))) /* ?{} */);
@@ -592,8 +592,8 @@
     int __i__i_1;
 };
-static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
 static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1);
 static inline void ___constructor__F_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
 static inline void ___destructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1);
+static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
 static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1){
     ((void)((*((int *)(&(*___dst__P14s__anonymous23_1).__i__i_1)))) /* ?{} */);
@@ -640,5 +640,5 @@
     int _tmp_cp_ret0;
     ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
-    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
     return ((int )___retval_main__i_1);
 }
Index: src/tests/.expect/64/extension.txt
===================================================================
--- src/tests/.expect/64/extension.txt	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/tests/.expect/64/extension.txt	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -13,8 +13,8 @@
     __extension__ int __c__i_1;
 };
-static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
 static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1);
 static inline void ___constructor__F_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
 static inline void ___destructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1);
+static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
 static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1){
     ((void)((*((int *)(&(*___dst__P2sS_1).__a__i_1)))) /* ?{} */);
@@ -93,5 +93,5 @@
     int _tmp_cp_ret0;
     ((void)((_tmp_cp_ret0=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret0));
-    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
     ((void)__extension__ sizeof(3));
     ((void)__extension__ (((int )(3!=((int )0))) || ((int )(4!=((int )0)))));
Index: src/tests/.expect/64/gccExtensions.txt
===================================================================
--- src/tests/.expect/64/gccExtensions.txt	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/tests/.expect/64/gccExtensions.txt	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -177,5 +177,5 @@
     int _tmp_cp_ret0;
     ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
-    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
     return ((int )___retval_main__i_1);
 }
Index: src/tests/Makefile.am
===================================================================
--- src/tests/Makefile.am	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/tests/Makefile.am	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -30,5 +30,5 @@
 
 all-local :
-	@+python test.py vector_test avl_test operators numericConstants expression enum array typeof cast dtor-early-exit init_once
+	@+python test.py vector_test avl_test operators numericConstants expression enum array typeof cast dtor-early-exit init_once coroutine
 
 all-tests :
Index: src/tests/Makefile.in
===================================================================
--- src/tests/Makefile.in	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/tests/Makefile.in	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -651,5 +651,5 @@
 
 all-local :
-	@+python test.py vector_test avl_test operators numericConstants expression enum array typeof cast dtor-early-exit init_once
+	@+python test.py vector_test avl_test operators numericConstants expression enum array typeof cast dtor-early-exit init_once coroutine
 
 all-tests :
Index: src/tests/vector/array.c
===================================================================
--- src/tests/vector/array.c	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/tests/vector/array.c	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -16,11 +16,8 @@
 #include "array.h"
 
-/// forall( otype array_type, elt_type | bounded_array( array_type, elt_type ) )
-/// [ array_iterator begin, array_iterator end ]
-/// get_iterators( array_type array )
-/// {
-///   begin = 0;
-///   end = last( array );
-/// }
+forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
+[ elt_type * begin, elt_type * end ] get_iterators( array_type * array ) {
+	return [ begin( array ), end( array ) ];
+}
 
 // The first element is always at index 0.
Index: src/tests/vector/array.h
===================================================================
--- src/tests/vector/array.h	(revision 6acb935ec45eabc0c4c2c47501d76a9c231f7219)
+++ src/tests/vector/array.h	(revision a362f977ce917e9868e8b98a81cc260e0aee5cf9)
@@ -32,8 +32,6 @@
 // implement iterator_for
 
-typedef int array_iterator;
-
-/// forall( otype array_type, elt_type | bounded_array( array_type, elt_type ) )
-/// [ array_iterator begin, array_iterator end ] get_iterators( array_type );
+forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
+[ elt_type * begin, elt_type * end ] get_iterators( array_type * );
 
 
