Index: src/ResolvExpr/AdjustExprType.cc
===================================================================
--- src/ResolvExpr/AdjustExprType.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/AdjustExprType.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -66,5 +66,5 @@
 
 	Type * AdjustExprType::postmutate( ArrayType * arrayType ) {
-		PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base );
+		PointerType *pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };
 		arrayType->base = nullptr;
 		delete arrayType;
@@ -73,19 +73,16 @@
 
 	Type * AdjustExprType::postmutate( FunctionType * functionType ) {
-		return new PointerType( Type::Qualifiers(), functionType );
+		return new PointerType{ Type::Qualifiers(), functionType };
 	}
 
 	Type * AdjustExprType::postmutate( TypeInstType * typeInst ) {
-		EqvClass eqvClass;
-		if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
-			if ( eqvClass.data.kind == TypeDecl::Ftype ) {
-				PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
-				return pointerType;
+		if ( const EqvClass* eqvClass = env.lookup( typeInst->get_name() ) ) {
+			if ( eqvClass->data.kind == TypeDecl::Ftype ) {
+				return new PointerType{ Type::Qualifiers(), typeInst };
 			}
 		} else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
 			if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
 				if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
-					PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
-					return pointerType;
+					return new PointerType{ Type::Qualifiers(), typeInst };
 				} // if
 			} // if
Index: src/ResolvExpr/Alternative.cc
===================================================================
--- src/ResolvExpr/Alternative.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/Alternative.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -27,5 +27,5 @@
 
 namespace ResolvExpr {
-	Alternative::Alternative() : cost( Cost::zero ), cvtCost( Cost::zero ), expr( 0 ) {}
+	Alternative::Alternative() : cost( Cost::zero ), cvtCost( Cost::zero ), expr( nullptr ) {}
 
 	Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost )
@@ -48,5 +48,5 @@
 	}
 
-	Alternative::Alternative( Alternative && other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ), env( other.env ) {
+	Alternative::Alternative( Alternative && other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ), env( std::move( other.env ) ) {
 		other.expr = nullptr;
 	}
@@ -58,5 +58,5 @@
 		cvtCost = other.cvtCost;
 		expr = other.expr;
-		env = other.env;
+		env = std::move( other.env );
 		other.expr = nullptr;
 		return *this;
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -102,5 +102,5 @@
 		void addAnonConversions( const Alternative & alt );
 		/// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
-		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
+		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name );
 		/// Adds alternatives for member expressions where the left side has tuple type
 		void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
@@ -307,26 +307,23 @@
 
 		if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
-			NameExpr nameExpr( "" );
-			addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
+			addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
 		} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
-			NameExpr nameExpr( "" );
-			addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
+			addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
 		} // if
 	}
 
 	template< typename StructOrUnionType >
-	void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
-		// by this point, member must be a name expr
-		NameExpr * nameExpr = dynamic_cast< NameExpr * >( member );
-		if ( ! nameExpr ) return;
-		const std::string & name = nameExpr->name;
+	void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ) {
 		std::list< Declaration* > members;
 		aggInst->lookup( name, members );
 
-		for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
-			if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
-				alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
-				renameTypes( alternatives.back().expr );
-				addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
+		for ( Declaration * decl : members ) {
+			if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
+				// addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
+				// can't construct in place and use vector::back
+				Alternative newAlt( new MemberExpr( dwt, expr->clone() ), env, newCost );
+				renameTypes( newAlt.expr );
+				addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
+				alternatives.push_back( std::move(newAlt) );
 			} else {
 				assert( false );
@@ -469,9 +466,5 @@
 	}
 
-	// /// Map of declaration uniqueIds (intended to be the assertions in an AssertionSet) to their parents and the number of times they've been included
-	//typedef std::unordered_map< UniqueId, std::unordered_map< UniqueId, unsigned > > AssertionParentSet;
-
 	static const int recursionLimit = /*10*/ 4;  ///< Limit to depth of recursion satisfaction
-	//static const unsigned recursionParentLimit = 1;  ///< Limit to the number of times an assertion can recursively use itself
 
 	void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
@@ -484,6 +477,5 @@
 
 	template< typename ForwardIterator, typename OutputIterator >
-	void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, /*const AssertionParentSet &needParents,*/
-						 int level, const SymTab::Indexer &indexer, OutputIterator out ) {
+	void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) {
 		if ( begin == end ) {
 			if ( newNeed.empty() ) {
@@ -503,5 +495,5 @@
 					printAssertionSet( newNeed, std::cerr, 8 );
 				)
-				inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, /*needParents,*/ level+1, indexer, out );
+				inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
 				return;
 			}
@@ -510,5 +502,5 @@
 		ForwardIterator cur = begin++;
 		if ( ! cur->second.isUsed ) {
-			inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out );
+			inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
 			return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
 		}
@@ -563,9 +555,4 @@
 				}
 
-				//AssertionParentSet newNeedParents( needParents );
-				// skip repeatingly-self-recursive assertion satisfaction
-				// DOESN'T WORK: grandchild nodes conflict with their cousins
-				//if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
-
 				Expression *varExpr = data.combine( newerAlt.cvtCost );
 				delete varExpr->get_result();
@@ -585,5 +572,5 @@
 				// XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
 				(*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
-				inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
+				inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
 			} else {
 				delete adjType;
@@ -607,5 +594,4 @@
 		addToIndexer( have, decls );
 		AssertionSet newNeed;
-		//AssertionParentSet needParents;
 		PRINT(
 			std::cerr << "env is: " << std::endl;
@@ -614,5 +600,5 @@
 		)
 
-		inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, /*needParents,*/ 0, indexer, out );
+		inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
 //	PRINT(
 //	    std::cerr << "declaration 14 is ";
@@ -1093,5 +1079,5 @@
 		AlternativeFinder funcOpFinder( indexer, env );
 		// it's ok if there aren't any defined function ops
-		funcOpFinder.maybeFind( opExpr);
+		funcOpFinder.maybeFind( opExpr );
 		PRINT(
 			std::cerr << "known function ops:" << std::endl;
@@ -1130,7 +1116,6 @@
 					}
 				} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
-					EqvClass eqvClass;
-					if ( func->env.lookup( typeInst->name, eqvClass ) && eqvClass.type ) {
-						if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
+					if ( const EqvClass *eqvClass = func->env.lookup( typeInst->name ) ) {
+						if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass->type ) ) {
 							Alternative newFunc( *func );
 							referenceToRvalueConversion( newFunc.expr, newFunc.cost );
@@ -1347,4 +1332,13 @@
 	}
 
+	namespace {
+		/// Gets name from untyped member expression (member must be NameExpr)
+		const std::string& get_member_name( UntypedMemberExpr *memberExpr ) {
+			NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() );
+			assert( nameExpr );
+			return nameExpr->get_name();
+		}
+	}
+
 	void AlternativeFinder::Finder::postvisit( UntypedMemberExpr *memberExpr ) {
 		AlternativeFinder funcFinder( indexer, env );
@@ -1359,7 +1353,7 @@
 			// find member of the given type
 			if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
-				addAggMembers( structInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
+				addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
 			} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
-				addAggMembers( unionInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
+				addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
 			} else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
 				addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() );
@@ -1379,5 +1373,8 @@
 			Cost cost = Cost::zero;
 			Expression * newExpr = data.combine( cost );
-			alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) );
+
+			// addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
+			// can't construct in place and use vector::back
+			Alternative newAlt( newExpr, env, Cost::zero, cost );
 			PRINT(
 				std::cerr << "decl is ";
@@ -1388,6 +1385,7 @@
 				std::cerr << std::endl;
 			)
-			renameTypes( alternatives.back().expr );
-			addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
+			renameTypes( newAlt.expr );
+			addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
+			alternatives.push_back( std::move(newAlt) );
 		} // for
 	}
Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/CastCost.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -43,13 +43,11 @@
 	Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			EqvClass eqvClass;
-			NamedTypeDecl *namedType;
-			if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
-				if ( eqvClass.type ) {
-					return castCost( src, eqvClass.type, indexer, env );
+			if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
+				if ( eqvClass->type ) {
+					return castCost( src, eqvClass->type, indexer, env );
 				} else {
 					return Cost::infinity;
 				}
-			} else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
+			} else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) {
 				// all typedefs should be gone by this point
 				TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType );
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/ConversionCost.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -42,14 +42,12 @@
 	Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			EqvClass eqvClass;
-			NamedTypeDecl *namedType;
 			PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
-			if ( env.lookup( destAsTypeInst->name, eqvClass ) ) {
-				if ( eqvClass.type ) {
-					return conversionCost( src, eqvClass.type, indexer, env );
+			if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
+				if ( eqvClass->type ) {
+					return conversionCost( src, eqvClass->type, indexer, env );
 				} else {
 					return Cost::infinity;
 				}
-			} else if ( ( namedType = indexer.lookupType( destAsTypeInst->name ) ) ) {
+			} else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
 				PRINT( std::cerr << " found" << std::endl; )
 				TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
@@ -369,13 +367,11 @@
 
 	void ConversionCost::postvisit( TypeInstType *inst ) {
-		EqvClass eqvClass;
-		NamedTypeDecl *namedType;
-		if ( env.lookup( inst->name, eqvClass ) ) {
-			cost = costFunc( eqvClass.type, dest, indexer, env );
+		if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
+			cost = costFunc( eqvClass->type, dest, indexer, env );
 		} else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
 				cost = Cost::zero;
 			}
-		} else if ( ( namedType = indexer.lookupType( inst->name ) ) ) {
+		} else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
 			TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
 			// all typedefs should be gone by this point
Index: src/ResolvExpr/Occurs.cc
===================================================================
--- src/ResolvExpr/Occurs.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/Occurs.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -38,7 +38,6 @@
 
 	Occurs::Occurs( std::string varName, const TypeEnvironment & env ) : result( false ), tenv( env ) {
-		EqvClass eqvClass;
-		if ( tenv.lookup( varName, eqvClass ) ) {
-			eqvVars = eqvClass.vars;
+		if ( const EqvClass *eqvClass = tenv.lookup( varName ) ) {
+			eqvVars = eqvClass->vars;
 		} else {
 			eqvVars.insert( varName );
@@ -47,16 +46,15 @@
 
 	void Occurs::previsit( TypeInstType * typeInst ) {
-		EqvClass eqvClass;
-///   std::cerr << "searching for vars: ";
+		///   std::cerr << "searching for vars: ";
 ///   std::copy( eqvVars.begin(), eqvVars.end(), std::ostream_iterator< std::string >( std::cerr, " " ) );
 ///   std::cerr << std::endl;
 		if ( eqvVars.find( typeInst->get_name() ) != eqvVars.end() ) {
 			result = true;
-		} else if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) {
-			if ( eqvClass.type ) {
+		} else if ( const EqvClass *eqvClass = tenv.lookup( typeInst->get_name() ) ) {
+			if ( eqvClass->type ) {
 ///       std::cerr << typeInst->get_name() << " is bound to";
 ///       eqvClass.type->print( std::cerr );
 ///       std::cerr << std::endl;
-				eqvClass.type->accept( *visitor );
+				eqvClass->type->accept( *visitor );
 			} // if
 		} // if
Index: src/ResolvExpr/PolyCost.cc
===================================================================
--- src/ResolvExpr/PolyCost.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/PolyCost.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -39,8 +39,7 @@
 
 	void PolyCost::previsit(TypeInstType * typeInst) {
-		EqvClass eqvClass;
-		if ( tenv.lookup( typeInst->name, eqvClass ) ) {
-			if ( eqvClass.type ) {
-				if ( TypeInstType * otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
+		if ( const EqvClass *eqvClass = tenv.lookup( typeInst->name ) ) {
+			if ( eqvClass->type ) {
+				if ( TypeInstType * otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass->type ) ) {
 					if ( indexer.lookupType( otherTypeInst->name ) ) {
 						// bound to opaque type
Index: src/ResolvExpr/PtrsAssignable.cc
===================================================================
--- src/ResolvExpr/PtrsAssignable.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/PtrsAssignable.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -51,7 +51,6 @@
 		// std::cerr << "assignable: " << src << " | " << dest << std::endl;
 		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			EqvClass eqvClass;
-			if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
-				return ptrsAssignable( src, eqvClass.type, env );
+			if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
+				return ptrsAssignable( src, eqvClass->type, env );
 			} // if
 		} // if
@@ -95,8 +94,9 @@
 	void PtrsAssignable::postvisit(  __attribute__((unused)) TraitInstType *inst ) {}
 	void PtrsAssignable::postvisit( TypeInstType *inst ) {
-		EqvClass eqvClass;
-		if ( env.lookup( inst->get_name(), eqvClass ) && eqvClass.type ) {
-			// T * = S * for any S depends on the type bound to T
-			result = ptrsAssignable( eqvClass.type, dest, env );
+		if ( const EqvClass *eqvClass = env.lookup( inst->get_name() ) ) {
+			if ( eqvClass->type ) {
+				// T * = S * for any S depends on the type bound to T
+				result = ptrsAssignable( eqvClass->type, dest, env );
+			}
 		} // if
 	}
Index: src/ResolvExpr/PtrsCastable.cc
===================================================================
--- src/ResolvExpr/PtrsCastable.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/PtrsCastable.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -57,5 +57,4 @@
 				return -1;
 			} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
-				EqvClass eqvClass;
 				if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
 					if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
@@ -64,6 +63,6 @@
 						} // if
 					} //if
-				} else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
-					if ( eqvClass.data.kind == TypeDecl::Ftype ) {
+				} else if ( const EqvClass *eqvClass = env.lookup( typeInst->get_name() ) ) {
+					if ( eqvClass->data.kind == TypeDecl::Ftype ) {
 						return -1;
 					} // if
@@ -79,8 +78,7 @@
 	int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
 		if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
-			EqvClass eqvClass;
-			if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
+			if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
 				// xxx - should this be ptrsCastable?
-				return ptrsAssignable( src, eqvClass.type, env );
+				return ptrsAssignable( src, eqvClass->type, env );
 			} // if
 		} // if
Index: src/ResolvExpr/TypeEnvironment.cc
===================================================================
--- src/ResolvExpr/TypeEnvironment.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/TypeEnvironment.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -17,5 +17,5 @@
 #include <algorithm>                   // for copy, set_intersection
 #include <iterator>                    // for ostream_iterator, insert_iterator
-#include <utility>                     // for pair
+#include <utility>                     // for pair, move
 
 #include "Common/utility.h"            // for maybeClone
@@ -44,15 +44,23 @@
 
 	void EqvClass::initialize( const EqvClass &src, EqvClass &dest ) {
+		initialize( src, dest, src.type );
+	}
+
+	void EqvClass::initialize( const EqvClass &src, EqvClass &dest, const Type *ty ) {
 		dest.vars = src.vars;
-		dest.type = maybeClone( src.type );
+		dest.type = maybeClone( ty );
 		dest.allowWidening = src.allowWidening;
 		dest.data = src.data;
 	}
 
-	EqvClass::EqvClass() : type( 0 ), allowWidening( true ) {
+	EqvClass::EqvClass() : type( nullptr ), allowWidening( true ) {
 	}
 
 	EqvClass::EqvClass( const EqvClass &other ) {
 		initialize( other, *this );
+	}
+
+	EqvClass::EqvClass( const EqvClass &other, const Type *ty ) {
+		initialize( other, *this, ty );
 	}
 
@@ -82,31 +90,38 @@
 	}
 
-	bool TypeEnvironment::lookup( const std::string &var, EqvClass &eqvClass ) const {
+	const EqvClass* TypeEnvironment::lookup( const std::string &var ) const {
 		for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
 			if ( i->vars.find( var ) != i->vars.end() ) {
 ///       std::cout << var << " is in class ";
 ///       i->print( std::cout );
-				eqvClass = *i;
-				return true;
+				return &*i;
 			}
 ///     std::cout << var << " is not in class ";
 ///     i->print( std::cout );
 		} // for
-		return false;
+		return nullptr;
+	}
+
+	/// Removes any class from env that intersects eqvClass
+	void filterOverlappingClasses( std::list<EqvClass> &env, const EqvClass &eqvClass ) {
+		for ( auto i = env.begin(); i != env.end(); ) {
+			auto next = i;
+			++next;
+			std::set<std::string> intersection;
+			std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(), 
+				std::inserter( intersection, intersection.begin() ) );
+			if ( ! intersection.empty() ) { env.erase( i ); }
+			i = next;
+		}
 	}
 
 	void TypeEnvironment::add( const EqvClass &eqvClass ) {
-		std::list< EqvClass >::iterator i = env.begin();
-		while ( i != env.end() ) {
-			std::list< EqvClass >::iterator next = i;
-			next++;
-			std::set< std::string > intersection;
-			std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(), std::inserter( intersection, intersection.begin() ) );
-			if ( ! intersection.empty() ) {
-				env.erase( i );
-			} // if
-			i = next;
-		} // while
-		env.insert( env.end(), eqvClass );
+		filterOverlappingClasses( env, eqvClass );
+		env.push_back( eqvClass );
+	}
+
+	void TypeEnvironment::add( EqvClass &&eqvClass ) {
+		filterOverlappingClasses( env, eqvClass );
+		env.push_back( std::move(eqvClass) );
 	}
 
@@ -159,6 +174,6 @@
 
 	void TypeEnvironment::print( std::ostream &os, Indenter indent ) const {
-		for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
-			i->print( os, indent );
+		for ( const EqvClass & theClass : env ) {
+			theClass.print( os, indent );
 		} // for
 	}
Index: src/ResolvExpr/TypeEnvironment.h
===================================================================
--- src/ResolvExpr/TypeEnvironment.h	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/TypeEnvironment.h	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -73,6 +73,8 @@
 
 		void initialize( const EqvClass &src, EqvClass &dest );
+		void initialize( const EqvClass &src, EqvClass &dest, const Type *ty );
 		EqvClass();
 		EqvClass( const EqvClass &other );
+		EqvClass( const EqvClass &other, const Type *ty );
 		EqvClass &operator=( const EqvClass &other );
 		~EqvClass();
@@ -82,6 +84,7 @@
 	class TypeEnvironment {
 	  public:
-		bool lookup( const std::string &var, EqvClass &eqvClass ) const;
+		const EqvClass* lookup( const std::string &var ) const;
 		void add( const EqvClass &eqvClass );
+		void add( EqvClass &&eqvClass  );
 		void add( const Type::ForallList &tyDecls );
 		void add( const TypeSubstitution & sub );
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/ResolvExpr/Unify.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -20,5 +20,5 @@
 #include <set>                    // for set
 #include <string>                 // for string, operator==, operator!=, bas...
-#include <utility>                // for pair
+#include <utility>                // for pair, move
 
 #include "Common/PassVisitor.h"   // for PassVisitor
@@ -166,17 +166,14 @@
 			return false;
 		} // if
-		EqvClass curClass;
-		if ( env.lookup( typeInst->get_name(), curClass ) ) {
-			if ( curClass.type ) {
+		if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) {
+			if ( curClass->type ) {
 				Type *common = 0;
 				// attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
-				std::unique_ptr< Type > newType( curClass.type->clone() );
+				std::unique_ptr< Type > newType( curClass->type->clone() );
 				newType->get_qualifiers() = typeInst->get_qualifiers();
-				if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
+				if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {
 					if ( common ) {
 						common->get_qualifiers() = Type::Qualifiers();
-						delete curClass.type;
-						curClass.type = common;
-						env.add( curClass );
+						env.add( EqvClass{ *curClass, common } );
 					} // if
 					return true;
@@ -185,8 +182,8 @@
 				} // if
 			} else {
-				curClass.type = other->clone();
-				curClass.type->get_qualifiers() = Type::Qualifiers();
-				curClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
-				env.add( curClass );
+				EqvClass newClass { *curClass, other };
+				newClass.type->get_qualifiers() = Type::Qualifiers();
+				newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
+				env.add( std::move(newClass) );
 			} // if
 		} else {
@@ -204,28 +201,26 @@
 	bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
 		bool result = true;
-		EqvClass class1, class2;
-		bool hasClass1 = false, hasClass2 = false;
+		const EqvClass *class1 = env.lookup( var1->get_name() );
+		const EqvClass *class2 = env.lookup( var2->get_name() );
 		bool widen1 = false, widen2 = false;
-		Type *type1 = 0, *type2 = 0;
-
-		if ( env.lookup( var1->get_name(), class1 ) ) {
-			hasClass1 = true;
-			if ( class1.type ) {
-				if ( occurs( class1.type, var2->get_name(), env ) ) {
+		Type *type1 = nullptr, *type2 = nullptr;
+
+		if ( class1 ) {
+			if ( class1->type ) {
+				if ( occurs( class1->type, var2->get_name(), env ) ) {
 					return false;
 				} // if
-				type1 = class1.type->clone();
-			} // if
-			widen1 = widenMode.widenFirst && class1.allowWidening;
-		} // if
-		if ( env.lookup( var2->get_name(), class2 ) ) {
-			hasClass2 = true;
-			if ( class2.type ) {
-				if ( occurs( class2.type, var1->get_name(), env ) ) {
+				type1 = class1->type->clone();
+			} // if
+			widen1 = widenMode.widenFirst && class1->allowWidening;
+		} // if
+		if ( class2 ) {
+			if ( class2->type ) {
+				if ( occurs( class2->type, var1->get_name(), env ) ) {
 					return false;
 				} // if
-				type2 = class2.type->clone();
-			} // if
-			widen2 = widenMode.widenSecond && class2.allowWidening;
+				type2 = class2->type->clone();
+			} // if
+			widen2 = widenMode.widenSecond && class2->allowWidening;
 		} // if
 
@@ -235,33 +230,38 @@
 			Type *common = 0;
 			if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
-				class1.vars.insert( class2.vars.begin(), class2.vars.end() );
-				class1.allowWidening = widen1 && widen2;
+				EqvClass newClass1 = *class1;
+				newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
+				newClass1.allowWidening = widen1 && widen2;
 				if ( common ) {
 					common->get_qualifiers() = Type::Qualifiers();
-					delete class1.type;
-					class1.type = common;
+					delete newClass1.type;
+					newClass1.type = common;
 				} // if
-				env.add( class1 );
+				env.add( std::move(newClass1) );
 			} else {
 				result = false;
 			} // if
-		} else if ( hasClass1 && hasClass2 ) {
+		} else if ( class1 && class2 ) {
 			if ( type1 ) {
-				class1.vars.insert( class2.vars.begin(), class2.vars.end() );
-				class1.allowWidening = widen1;
-				env.add( class1 );
+				EqvClass newClass1 = *class1;
+				newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
+				newClass1.allowWidening = widen1;
+				env.add( std::move(newClass1) );
 			} else {
-				class2.vars.insert( class1.vars.begin(), class1.vars.end() );
-				class2.allowWidening = widen2;
-				env.add( class2 );
-			} // if
-		} else if ( hasClass1 ) {
-			class1.vars.insert( var2->get_name() );
-			class1.allowWidening = widen1;
-			env.add( class1 );
-		} else if ( hasClass2 ) {
-			class2.vars.insert( var1->get_name() );
-			class2.allowWidening = widen2;
-			env.add( class2 );
+				EqvClass newClass2 = *class2;
+				newClass2.vars.insert( class1->vars.begin(), class1->vars.end() );
+				newClass2.allowWidening = widen2;
+				env.add( std::move(newClass2) );
+			} // if
+		} else if ( class1 ) {
+			EqvClass newClass1 = *class1;
+			newClass1.vars.insert( var2->get_name() );
+			newClass1.allowWidening = widen1;
+			env.add( std::move(newClass1) );
+		} else if ( class2 ) {
+			EqvClass newClass2 = *class2;
+			newClass2.vars.insert( var1->get_name() );
+			newClass2.allowWidening = widen2;
+			env.add( std::move(newClass2) );
 		} else {
 			EqvClass newClass;
@@ -539,12 +539,9 @@
 		void premutate( TypeInstType * ) { visit_children = false; }
 		Type * postmutate( TypeInstType * typeInst ) {
-			EqvClass eqvClass;
-			if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) {
-				if ( eqvClass.data.kind == TypeDecl::Ttype ) {
-					// expand ttype parameter into its actual type
-					if ( eqvClass.type ) {
-						delete typeInst;
-						return eqvClass.type->clone();
-					}
+			if ( const EqvClass *eqvClass = tenv.lookup( typeInst->get_name() ) ) {
+				// expand ttype parameter into its actual type
+				if ( eqvClass->data.kind == TypeDecl::Ttype && eqvClass->type ) {
+					delete typeInst;
+					return eqvClass->type->clone();
 				}
 			}
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/SynTree/ReferenceToType.cc	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -50,8 +50,8 @@
 
 namespace {
-	void doLookup( const std::list< Declaration* > &members, const std::string &name, std::list< Declaration* > &foundDecls ) {
-		for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
-			if ( (*i)->get_name() == name ) {
-				foundDecls.push_back( *i );
+	void doLookup( const std::list< Declaration * > & members, const std::string & name, std::list< Declaration* > & foundDecls ) {
+		for ( Declaration * decl : members ) {
+			if ( decl->name == name ) {
+				foundDecls.push_back( decl );
 			} // if
 		} // for
@@ -60,5 +60,5 @@
 
 StructInstType::StructInstType( const Type::Qualifiers & tq, StructDecl * baseStruct, const std::list< Attribute * > & attributes ) :
-		Parent( tq, baseStruct->get_name(), attributes ), baseStruct( baseStruct ) {}
+		Parent( tq, baseStruct->name, attributes ), baseStruct( baseStruct ) {}
 
 std::string StructInstType::typeString() const { return "struct"; }
@@ -84,5 +84,5 @@
 void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
 	assert( baseStruct );
-	doLookup( baseStruct->get_members(), name, foundDecls );
+	doLookup( baseStruct->members, name, foundDecls );
 }
 
@@ -103,5 +103,5 @@
 
 UnionInstType::UnionInstType( const Type::Qualifiers & tq, UnionDecl * baseUnion, const std::list< Attribute * > & attributes ) :
-		Parent( tq, baseUnion->get_name(), attributes ), baseUnion( baseUnion ) {}
+		Parent( tq, baseUnion->name, attributes ), baseUnion( baseUnion ) {}
 
 std::string UnionInstType::typeString() const { return "union"; }
@@ -127,5 +127,5 @@
 void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
 	assert( baseUnion );
-	doLookup( baseUnion->get_members(), name, foundDecls );
+	doLookup( baseUnion->members, name, foundDecls );
 }
 
Index: src/benchmark/Makefile.am
===================================================================
--- src/benchmark/Makefile.am	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/benchmark/Makefile.am	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -96,23 +96,35 @@
 	ctxswitch-cfa_coroutine.run	\
 	ctxswitch-cfa_thread.run	\
+	ctxswitch-cfa_thread2.run	\
 	ctxswitch-upp_coroutine.run	\
 	ctxswitch-upp_thread.run	\
+	-ctxswitch-kos_fibre.run	\
+	-ctxswitch-kos_fibre2.run	\
 	ctxswitch-goroutine.run		\
 	ctxswitch-java_thread.run
 
+ctxswitch-pthread$(EXEEXT):
+	@@BACKEND_CC@ ctxswitch/pthreads.c     -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+
 ctxswitch-cfa_coroutine$(EXEEXT):
-	@${CC}        ctxswitch/cfa_cor.c   -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+	@${CC}        ctxswitch/cfa_cor.c      -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
 
 ctxswitch-cfa_thread$(EXEEXT):
-	@${CC}        ctxswitch/cfa_thrd.c  -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+	@${CC}        ctxswitch/cfa_thrd.c     -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+
+ctxswitch-cfa_thread2$(EXEEXT):
+	@${CC}        ctxswitch/cfa_thrd2.c    -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
 
 ctxswitch-upp_coroutine$(EXEEXT):
-	@u++          ctxswitch/upp_cor.cc  -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+	@u++          ctxswitch/upp_cor.cc     -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
 
 ctxswitch-upp_thread$(EXEEXT):
-	@u++          ctxswitch/upp_thrd.cc -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
-
-ctxswitch-pthread$(EXEEXT):
-	@@BACKEND_CC@ ctxswitch/pthreads.c  -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+	@u++          ctxswitch/upp_thrd.cc    -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+
+ctxswitch-kos_fibre$(EXEEXT):
+	@${CXX}       ctxswitch/kos_fibre.cpp  -DBENCH_N=50000000  -I. -I/home/tdelisle/software/KOS/src/ -g -O2 -lfibre -lpthread -lrt
+
+ctxswitch-kos_fibre2$(EXEEXT):
+	@${CXX}       ctxswitch/kos_fibre2.cpp -DBENCH_N=50000000  -I. -I/home/tdelisle/software/KOS/src/ -g -O2 -lfibre -lpthread -lrt
 
 ctxswitch-goroutine$(EXEEXT):
Index: src/benchmark/Makefile.in
===================================================================
--- src/benchmark/Makefile.in	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/benchmark/Makefile.in	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -509,23 +509,35 @@
 	ctxswitch-cfa_coroutine.run	\
 	ctxswitch-cfa_thread.run	\
+	ctxswitch-cfa_thread2.run	\
 	ctxswitch-upp_coroutine.run	\
 	ctxswitch-upp_thread.run	\
+	-ctxswitch-kos_fibre.run	\
+	-ctxswitch-kos_fibre2.run	\
 	ctxswitch-goroutine.run		\
 	ctxswitch-java_thread.run
 
+ctxswitch-pthread$(EXEEXT):
+	@@BACKEND_CC@ ctxswitch/pthreads.c     -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+
 ctxswitch-cfa_coroutine$(EXEEXT):
-	@${CC}        ctxswitch/cfa_cor.c   -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+	@${CC}        ctxswitch/cfa_cor.c      -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
 
 ctxswitch-cfa_thread$(EXEEXT):
-	@${CC}        ctxswitch/cfa_thrd.c  -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+	@${CC}        ctxswitch/cfa_thrd.c     -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+
+ctxswitch-cfa_thread2$(EXEEXT):
+	@${CC}        ctxswitch/cfa_thrd2.c    -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
 
 ctxswitch-upp_coroutine$(EXEEXT):
-	@u++          ctxswitch/upp_cor.cc  -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+	@u++          ctxswitch/upp_cor.cc     -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
 
 ctxswitch-upp_thread$(EXEEXT):
-	@u++          ctxswitch/upp_thrd.cc -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
-
-ctxswitch-pthread$(EXEEXT):
-	@@BACKEND_CC@ ctxswitch/pthreads.c  -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+	@u++          ctxswitch/upp_thrd.cc    -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+
+ctxswitch-kos_fibre$(EXEEXT):
+	@${CXX}       ctxswitch/kos_fibre.cpp  -DBENCH_N=50000000  -I. -I/home/tdelisle/software/KOS/src/ -g -O2 -lfibre -lpthread -lrt
+
+ctxswitch-kos_fibre2$(EXEEXT):
+	@${CXX}       ctxswitch/kos_fibre2.cpp -DBENCH_N=50000000  -I. -I/home/tdelisle/software/KOS/src/ -g -O2 -lfibre -lpthread -lrt
 
 ctxswitch-goroutine$(EXEEXT):
@@ -682,8 +694,8 @@
 
 compile-io$(EXEEXT):
-	@${CC} -quiet -fsyntax-only -w ../tests/io.c					@CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+	@${CC} -quiet -fsyntax-only -w ../tests/io1.c				@CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
 
 compile-monitor$(EXEEXT):
-	@${CC} -quiet -fsyntax-only -w ../tests/concurrent/monitor.c		@CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+	@${CC} -quiet -fsyntax-only -w ../tests/concurrent/monitor.c	@CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
 
 compile-operators$(EXEEXT):
@@ -694,5 +706,5 @@
 
 compile-typeof$(EXEEXT):
-	@${CC} -quiet -fsyntax-only -w ../tests/typeof.c				@CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
+	@${CC} -quiet -fsyntax-only -w ../tests/typeof.c			@CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
Index: src/benchmark/ctxswitch/cfa_thrd2.c
===================================================================
--- src/benchmark/ctxswitch/cfa_thrd2.c	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
+++ src/benchmark/ctxswitch/cfa_thrd2.c	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <thread>
+
+#include "bench.h"
+
+volatile bool done = false;
+
+thread Fibre {};
+
+void main(Fibre & this) {
+	while(!done) {
+		yield();
+	}
+}
+
+int main(int argc, char* argv[]) {
+	Fibre f1;
+  	BENCH(
+		for (size_t i = 0; i < n; i++) {
+			yield();
+		},
+		result
+	)
+
+	printf("%llu\n", result);
+	done = true;
+	return 0;
+}
Index: src/benchmark/ctxswitch/kos_fibre.cpp
===================================================================
--- src/benchmark/ctxswitch/kos_fibre.cpp	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
+++ src/benchmark/ctxswitch/kos_fibre.cpp	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -0,0 +1,14 @@
+#include <libfibre/fibre.h>
+
+#include "bench.h"
+
+int main(int argc, char* argv[]) {
+	BENCH(
+		for (size_t i = 0; i < n; i++) {
+			Fibre::yield();
+		},
+		result
+	)
+	printf("%llu\n", result);
+	return 0;
+}
Index: src/benchmark/ctxswitch/kos_fibre2.cpp
===================================================================
--- src/benchmark/ctxswitch/kos_fibre2.cpp	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
+++ src/benchmark/ctxswitch/kos_fibre2.cpp	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -0,0 +1,26 @@
+#include <libfibre/fibre.h>
+
+#include "bench.h"
+
+volatile bool done = false;
+
+static void f1main() {
+	while(!done) {
+		Fibre::yield();
+	}
+}
+
+int main(int argc, char* argv[]) {
+	Fibre* f1 = (new Fibre)->run(f1main);
+  	BENCH(
+		for (size_t i = 0; i < n; i++) {
+			Fibre::yield();
+		},
+		result
+	)
+	printf("%llu\n", result);
+	done = true;
+	Fibre::yield();
+	f1->join();
+	return 0;
+}
Index: src/libcfa/concurrency/invoke.h
===================================================================
--- src/libcfa/concurrency/invoke.h	(revision ecae5860965de56ce3fadb77f1a7686686e37c67)
+++ src/libcfa/concurrency/invoke.h	(revision adb6a4f131728a0c59ebb11aef3189b149895233)
@@ -10,6 +10,6 @@
 // Created On       : Tue Jan 17 12:27:26 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Mar 30 22:33:59 2018
-// Update Count     : 30
+// Last Modified On : Sat May 19 08:23:21 2018
+// Update Count     : 31
 //
 
@@ -18,7 +18,4 @@
 #include "bits/locks.h"
 
-#define TL_GET( member ) kernelTLS.member
-#define TL_SET( member, value ) kernelTLS.member = value;
-
 #ifdef __cforall
 extern "C" {
@@ -28,4 +25,22 @@
 #ifndef _INVOKE_H_
 #define _INVOKE_H_
+
+#ifdef __ARM_ARCH
+	// function prototypes are only really used by these macros on ARM
+	void disable_global_interrupts();
+	void enable_global_interrupts();
+
+	#define TL_GET( member ) ( { __typeof__( kernelTLS.member ) target; \
+                disable_global_interrupts(); \
+                target = kernelTLS.member; \
+                enable_global_interrupts(); \
+                target; } )
+	#define TL_SET( member, value ) disable_global_interrupts(); \
+		kernelTLS.member = value; \
+		enable_global_interrupts();
+#else
+	#define TL_GET( member ) kernelTLS.member
+	#define TL_SET( member, value ) kernelTLS.member = value;
+#endif
 
 	#ifdef __cforall
