Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/CodeGen/CodeGenerator.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -336,35 +336,4 @@
 			if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) {
 				std::list< Expression* >::iterator arg = applicationExpr->get_args().begin();
-				switch ( opInfo.type ) {
-				  case OT_PREFIXASSIGN:
-				  case OT_POSTFIXASSIGN:
-				  case OT_INFIXASSIGN:
-				  case OT_CTOR:
-				  case OT_DTOR:
-					{
-						assert( arg != applicationExpr->get_args().end() );
-						if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
-							// remove & from first assignment/ctor argument
-							*arg = addrExpr->get_arg();
-						} else {
-							// no address-of operator, so must be a pointer - add dereference
-							// NOTE: if the assertion starts to trigger, check that the application expr isn't being shared.
-							// Since its arguments are modified here, this assertion most commonly triggers when the application
-							// is visited multiple times.
-							UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) );
-							newExpr->get_args().push_back( *arg );
-							Type * type = InitTweak::getPointerBase( (*arg)->get_result() );
-							assertf( type, "First argument to a derefence must be a pointer. Ensure that expressions are not being shared." );
-							newExpr->set_result( type->clone() );
-							*arg = newExpr;
-						} // if
-						break;
-					}
-
-				  default:
-					// do nothing
-					;
-				} // switch
-
 				switch ( opInfo.type ) {
 				  case OT_INDEX:
Index: src/CodeGen/GenType.cc
===================================================================
--- src/CodeGen/GenType.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/CodeGen/GenType.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -37,4 +37,5 @@
 		virtual void visit( PointerType *pointerType );
 		virtual void visit( ArrayType *arrayType );
+		virtual void visit( ReferenceType *refType );
 		virtual void visit( StructInstType *structInst );
 		virtual void visit( UnionInstType *unionInst );
@@ -147,4 +148,12 @@
 	}
 
+	void GenType::visit( ReferenceType *refType ) {
+		assert( refType->get_base() != 0);
+		assertf( ! genC, "Reference types should not reach code generation." );
+		handleQualifiers( refType );
+		typeString = "&" + typeString;
+		refType->get_base()->accept( *this );
+	}
+
 	void GenType::visit( FunctionType *funcType ) {
 		std::ostringstream os;
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/Common/PassVisitor.h	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -113,4 +113,5 @@
 	virtual void visit( PointerType *pointerType ) override final;
 	virtual void visit( ArrayType *arrayType ) override final;
+	virtual void visit( ReferenceType *referenceType ) override final;
 	virtual void visit( FunctionType *functionType ) override final;
 	virtual void visit( StructInstType *aggregateUseType ) override final;
@@ -198,4 +199,5 @@
 	virtual Type* mutate( PointerType *pointerType ) override final;
 	virtual Type* mutate( ArrayType *arrayType ) override final;
+	virtual Type* mutate( ReferenceType *referenceType ) override final;
 	virtual Type* mutate( FunctionType *functionType ) override final;
 	virtual Type* mutate( StructInstType *aggregateUseType ) override final;
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/Common/PassVisitor.impl.h	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -786,4 +786,9 @@
 
 template< typename pass_type >
+void PassVisitor< pass_type >::visit( ReferenceType * node ) {
+	VISIT_BODY( node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( FunctionType * node ) {
 	VISIT_BODY( node );
@@ -1118,4 +1123,9 @@
 
 template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) {
+	MUTATE_BODY( Type, node );
+}
+
+template< typename pass_type >
 Type * PassVisitor< pass_type >::mutate( FunctionType * node ) {
 	MUTATE_BODY( Type, node );
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/Concurrency/Keywords.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -524,7 +524,5 @@
 
 		DeclarationWithType * param = decl->get_functionType()->get_parameters().front();
-		auto ptr = dynamic_cast< PointerType * >( param->get_type() );
-		// if( ptr ) std::cerr << "FRED1" << std::endl;
-		auto type  = dynamic_cast< StructInstType * >( ptr->get_base() );
+		auto type  = dynamic_cast< StructInstType * >( InitTweak::getPointerBase( param->get_type() ) );
 		// if( type ) std::cerr << "FRED2" << std::endl;
 		if( type && type->get_baseStruct()->is_thread() ) {
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/GenPoly/Box.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -758,5 +758,6 @@
 					// if the argument's type is polymorphic, we don't need to box again!
 					return;
-				} else if ( arg->get_result()->get_lvalue() ) {
+				} else if ( arg->get_result()->get_lvalue() ) {  // xxx - is this still right??
+				// xxx - dynamic_cast<ReferenceType *>( arg->get_result() )??
 					// VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
 					// xxx - need to test that this code is still reachable
@@ -1036,5 +1037,6 @@
 						assert( appExpr->has_result() );
 						assert( ! appExpr->get_args().empty() );
-						if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) {
+						if ( isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) { // dereference returns a reference type
+							// remove dereference from polymorphic types since they are boxed.
 							Expression *ret = appExpr->get_args().front();
 							delete ret->get_result();
Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/GenPoly/Lvalue.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -32,24 +32,26 @@
 #include "Common/UniqueName.h"
 #include "Common/utility.h"
+#include "InitTweak/InitTweak.h"
+
+#include "Common/PassVisitor.h"
+
+// need to be careful about polymorphic references... e.g. in *? (___operator_deref__A0_1_0_0__Fd0_Pd0_intrinsic___1)
+// the variable is automatically dereferenced and this causes errors dereferencing void*.
 
 namespace GenPoly {
 	namespace {
-		/// Replace uses of lvalue returns with appropriate pointers
-		class Pass1 : public Mutator {
-		  public:
-			Pass1();
-
-			virtual Expression *mutate( ApplicationExpr *appExpr );
-			virtual Statement *mutate( ReturnStmt *appExpr );
-			virtual DeclarationWithType *mutate( FunctionDecl *funDecl );
-		  private:
-			DeclarationWithType* retval;
-		};
-
-		/// Replace declarations of lvalue returns with appropriate pointers
-		class Pass2 : public Visitor {
-		  public:
-			virtual void visit( FunctionType *funType );
-		  private:
+		struct ReferenceConversions final {
+			Expression * postmutate( CastExpr * castExpr );
+		};
+
+		/// Intrinsic functions that take reference parameters don't REALLY take reference parameters -- their reference arguments must always be implicitly dereferenced.
+		struct FixIntrinsicArgs final {
+			Expression * postmutate( ApplicationExpr *appExpr );
+		};
+
+
+		/// Replace reference types with pointer types
+		struct ReferenceTypeElimination final {
+			Type * postmutate( ReferenceType * refType );
 		};
 
@@ -57,17 +59,18 @@
 		/// https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Lvalues.html#Lvalues
 		/// Replaces &(a,b) with (a, &b), &(a ? b : c) with (a ? &b : &c)
-		class GeneralizedLvalue : public Mutator {
-			typedef Mutator Parent;
-
-			virtual Expression * mutate( AddressExpr * addressExpr );
+		struct GeneralizedLvalue final {
+			Expression * postmutate( AddressExpr * addressExpr );
 		};
 	} // namespace
 
 	void convertLvalue( std::list< Declaration* >& translationUnit ) {
-		Pass1 p1;
-		Pass2 p2;
-		GeneralizedLvalue genLval;
-		mutateAll( translationUnit, p1 );
-		acceptAll( translationUnit, p2 );
+		std::cerr << "convertLvalue" << std::endl;
+		PassVisitor<ReferenceConversions> refCvt;
+		PassVisitor<ReferenceTypeElimination> elim;
+		PassVisitor<GeneralizedLvalue> genLval;
+		PassVisitor<FixIntrinsicArgs> fixer;
+		mutateAll( translationUnit, refCvt );
+		mutateAll( translationUnit, fixer );
+		mutateAll( translationUnit, elim );
 		mutateAll( translationUnit, genLval );
 	}
@@ -77,5 +80,5 @@
 			if ( function->get_returnVals().empty() ) return 0;
 			Type *ty = function->get_returnVals().front()->get_type();
-			return ty->get_lvalue() ? ty : 0;
+			return dynamic_cast< ReferenceType * >( ty ) ;
 		}
 
@@ -88,81 +91,138 @@
 		}
 
-		Pass1::Pass1() {
-		}
-
-		DeclarationWithType * Pass1::mutate( FunctionDecl *funcDecl ) {
-			if ( funcDecl->get_statements() ) {
-				DeclarationWithType* oldRetval = retval;
-				retval = 0;
-				if ( ! LinkageSpec::isBuiltin( funcDecl->get_linkage() ) && isLvalueRet( funcDecl->get_functionType() ) ) {
-					retval = funcDecl->get_functionType()->get_returnVals().front();
-				}
-				// fix expressions and return statements in this function
-				funcDecl->set_statements( funcDecl->get_statements()->acceptMutator( *this ) );
-				retval = oldRetval;
-			} // if
-			return funcDecl;
-		}
-
-		Expression * Pass1::mutate( ApplicationExpr *appExpr ) {
-			appExpr->get_function()->acceptMutator( *this );
-			mutateAll( appExpr->get_args(), *this );
-
-			PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
-			FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
-
-			Type *funType = isLvalueRet( function );
-			if ( funType && ! isIntrinsicApp( appExpr ) ) {
-				Expression *expr = appExpr;
-				Type *appType = appExpr->get_result();
-				if ( isPolyType( funType ) && ! isPolyType( appType ) ) {
-					// make sure cast for polymorphic type is inside dereference
-					expr = new CastExpr( appExpr, new PointerType( Type::Qualifiers(), appType->clone() ) );
-				}
-				UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
-				deref->set_result( appType->clone() );
-				appExpr->set_result( new PointerType( Type::Qualifiers(), appType ) );
-				deref->get_args().push_back( expr );
+		bool isDeref( Expression * expr ) {
+			if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) {
+				return InitTweak::getFunctionName( untyped ) == "*?";
+			} else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) {
+				if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) {
+					return func->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getFunctionName( appExpr ) == "*?";
+				}
+			}
+			return false;
+		}
+
+		bool isIntrinsicReference( Expression * expr ) {
+			if ( isDeref( expr ) ) return true;
+			else if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) {
+				return InitTweak::getFunctionName( untyped ) == "?[?]";
+			} else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) {
+				if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) {
+					return func->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getFunctionName( appExpr ) == "?[?]";
+				}
+			}
+			return false;
+		}
+
+		void fixArg( Expression *& arg, Type * formal ) {
+			// if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( arg ) ) {
+				if ( dynamic_cast<ReferenceType*>( formal ) ) { // xxx - but might be deref, in which case result isn't REALLY a reference, at least not in the sense that we need to add another deref...
+					// doesn't work, for some reason left arg is skipped in assign
+					ReferenceType * refType = safe_dynamic_cast< ReferenceType * >( arg->get_result() ) ;
+					std::cerr << "appexpr arg is non-deref/index intrinsic call" << std::endl;
+					std::cerr << arg << std::endl;
+					PointerType * ptrType = new PointerType( Type::Qualifiers(), refType->get_base()->clone() );
+					delete refType;
+					arg->set_result( ptrType );
+					arg = UntypedExpr::createDeref( arg );
+				}
+
+			// }
+		}
+
+		Expression * FixIntrinsicArgs::postmutate( ApplicationExpr * appExpr ) {
+			if ( DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) {
+				if ( function->get_linkage() == LinkageSpec::Intrinsic ) { // intrinsic functions that turn pointers into references
+					FunctionType * ftype = GenPoly::getFunctionType( function->get_type() );
+					assertf( ftype, "Function declaration does not have function type." );
+					for ( auto p : group_iterate( appExpr->get_args(), ftype->get_parameters() ) ) {
+						Expression *& arg = std::get<0>( p );
+						DeclarationWithType * formal = std::get<1>( p );
+						std::cerr << "pair<0>: " << arg << std::endl;
+						std::cerr << "pair<1>: " << formal->get_type() << std::endl;
+						if ( isIntrinsicReference( arg ) ) {
+							std::cerr << "skipping intrinsic reference" << std::endl;
+							continue;
+						} else {
+							fixArg( arg, formal->get_type() );
+						}
+					}
+				}
+			}
+			return appExpr;
+		}
+
+		Expression * ReferenceConversions::postmutate( CastExpr * castExpr ) {
+			// conversion to reference type
+			if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( castExpr->get_result() ) ) {
+				(void)refType;
+				if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( castExpr->get_arg()->get_result() ) ) {
+					// nothing to do if casting from reference to reference.
+					(void)otherRef;
+					std::cerr << "convert reference to reference -- nop" << std::endl;
+					if ( isIntrinsicReference( castExpr->get_arg() ) ) {
+						Expression * callExpr = castExpr->get_arg();
+						Expression ** arg = nullptr;
+						Expression *& arg0 = InitTweak::getCallArg( callExpr, 0 );
+						if ( dynamic_cast<PointerType *>( arg0->get_result() ) ) {
+							arg = &arg0;
+						} else {
+							arg = &InitTweak::getCallArg( callExpr, 1 );
+						}
+
+						castExpr->set_arg( *arg );
+						*arg = castExpr;
+						std::cerr << "but arg is deref -- &" << std::endl;
+						std::cerr << callExpr << std::endl;
+						// castExpr->set_arg( new AddressExpr( castExpr->get_arg() ) );
+
+						// move environment out to new top-level
+						callExpr->set_env( castExpr->get_env() );
+						castExpr->set_env( nullptr );
+						return callExpr;
+					}
+					std::cerr << castExpr << std::endl;
+					return castExpr;
+				} else if ( castExpr->get_arg()->get_result()->get_lvalue() ) {
+					// conversion from lvalue to reference
+					// xxx - keep cast, but turn into pointer cast??
+					// xxx - memory
+					std::cerr << "convert lvalue to reference -- &" << std::endl;
+					std::cerr << castExpr->get_arg() << std::endl;
+					castExpr->set_arg( new AddressExpr( castExpr->get_arg() ) );
+					// return new AddressExpr( castExpr->get_arg() );
+					return castExpr;
+				} else {
+					// rvalue to reference conversion -- introduce temporary
+				}
+				assertf( false, "Only conversions to reference from lvalue are currently supported: %s", toString( castExpr ).c_str() );
+			} else if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( castExpr->get_arg()->get_result() ) ) {
+				// should be easy, just need to move deref code up here?
+				std::cerr << "convert reference to rvalue -- *" << std::endl;
+				if ( isIntrinsicReference( castExpr->get_arg() ) ) {
+					std::cerr << "but arg is intrinsic reference -- nop" << std::endl;
+					return castExpr;
+				}
+				std::cerr << castExpr << std::endl;
+
+				PointerType * ptrType = new PointerType( refType->get_qualifiers(), refType->get_base()->clone() );
+				delete castExpr->get_result();
+				castExpr->set_result( ptrType );
+				Expression * deref = UntypedExpr::createDeref( castExpr );
+				deref->set_env( castExpr->get_env() );
+				castExpr->set_env( nullptr );
 				return deref;
-			} else {
-				return appExpr;
-			} // if
-		}
-
-		Statement * Pass1::mutate(ReturnStmt *retStmt) {
-			if ( retval && retStmt->get_expr() ) {
-				if ( retStmt->get_expr()->get_result()->get_lvalue() ) {
-					// ***** Code Removal ***** because casts may be stripped already
-
-					// strip casts because not allowed to take address of cast
-					// while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
-					// 	retStmt->set_expr( castExpr->get_arg() );
-					// 	retStmt->get_expr()->set_env( castExpr->get_env() );
-					// 	castExpr->set_env( 0 );
-					// 	castExpr->set_arg( 0 );
-					// 	delete castExpr;
-					// } // while
-					retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) );
-				} else {
-					throw SemanticError( "Attempt to return non-lvalue from an lvalue-qualified function" );
-				} // if
-			} // if
-			return retStmt;
-		}
-
-		void Pass2::visit( FunctionType *funType ) {
-			std::string typeName;
-			if ( isLvalueRet( funType ) ) {
-				DeclarationWithType *retParm = funType->get_returnVals().front();
-
-				// make a new parameter that is a pointer to the type of the old return value
-				retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );
-			} // if
-
-			Visitor::visit( funType );
-		}
-
-		Expression * GeneralizedLvalue::mutate( AddressExpr * addrExpr ) {
-			addrExpr = safe_dynamic_cast< AddressExpr * >( Parent::mutate( addrExpr ) );
+				// assertf( false, "Conversions from reference types are not currently supported." );
+			}
+			return castExpr;
+		}
+
+		Type * ReferenceTypeElimination::postmutate( ReferenceType * refType ) {
+			Type * base = refType->get_base();
+			refType->set_base( nullptr );
+			delete refType;
+			return new PointerType( Type::Qualifiers(), base );
+		}
+
+		Expression * GeneralizedLvalue::postmutate( AddressExpr * addrExpr ) {
 			if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( addrExpr->get_arg() ) ) {
 				Expression * arg1 = commaExpr->get_arg1()->clone();
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/InitTweak/FixInit.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -364,9 +364,9 @@
 					assert( ftype );
 					if ( isConstructor( funcDecl->get_name() ) && ftype->get_parameters().size() == 2 ) {
-						Type * t1 = ftype->get_parameters().front()->get_type();
+						Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() );
 						Type * t2 = ftype->get_parameters().back()->get_type();
-						PointerType * ptrType = safe_dynamic_cast< PointerType * > ( t1 );
-
-						if ( ResolvExpr::typesCompatible( ptrType->get_base(), t2, SymTab::Indexer() ) ) {
+						assert( t1 );
+
+						if ( ResolvExpr::typesCompatible( t1, t2, SymTab::Indexer() ) ) {
 							// optimization: don't need to copy construct in order to call a copy constructor
 							return appExpr;
@@ -401,5 +401,5 @@
 
 		bool ResolveCopyCtors::skipCopyConstruct( Type * type ) {
-			return dynamic_cast< VarArgsType * >( type ) || GenPoly::getFunctionType( type ) || Tuples::isTtype( type );
+			return dynamic_cast< VarArgsType * >( type ) || dynamic_cast< ReferenceType * >( type ) || GenPoly::getFunctionType( type ) || Tuples::isTtype( type );
 		}
 
@@ -489,5 +489,5 @@
 				impCpCtorExpr->get_returnDecls().push_back( ret );
 				CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
-				if ( ! result->get_lvalue() ) {
+				if ( ! dynamic_cast< ReferenceType * >( result ) ) {
 					// destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
 					destructRet( ret, impCpCtorExpr );
@@ -997,6 +997,6 @@
 				assert( ! type->get_parameters().empty() );
 				thisParam = safe_dynamic_cast< ObjectDecl * >( type->get_parameters().front() );
-				PointerType * ptrType = safe_dynamic_cast< PointerType * > ( thisParam->get_type() );
-				StructInstType * structType = dynamic_cast< StructInstType * >( ptrType->get_base() );
+				Type * thisType = getPointerBase( thisParam->get_type() );
+				StructInstType * structType = dynamic_cast< StructInstType * >( thisType );
 				if ( structType ) {
 					structDecl = structType->get_baseStruct();
@@ -1046,6 +1046,4 @@
 					// insert and resolve default/copy constructor call for each field that's unhandled
 					std::list< Statement * > stmt;
-					UntypedExpr * deref = UntypedExpr::createDeref( new VariableExpr( thisParam ) );
-
 					Expression * arg2 = 0;
 					if ( isCopyConstructor( function ) ) {
@@ -1056,5 +1054,5 @@
 					}
 					InitExpander srcParam( arg2 );
-					SymTab::genImplicitCall( srcParam, new MemberExpr( field, deref ), function->get_name(), back_inserter( stmt ), field, isCtor );
+					SymTab::genImplicitCall( srcParam, new MemberExpr( field, new VariableExpr( thisParam ) ), function->get_name(), back_inserter( stmt ), field, isCtor );
 
 					assert( stmt.size() <= 1 );
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/InitTweak/GenInit.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -54,5 +54,5 @@
 
 	  protected:
-		FunctionType * ftype;
+		FunctionType * ftype = nullptr;
 		std::string funcName;
 	};
@@ -137,13 +137,11 @@
 		std::list< DeclarationWithType * > & returnVals = ftype->get_returnVals();
 		assert( returnVals.size() == 0 || returnVals.size() == 1 );
-		// hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address
+		// hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address
 		// is being returned
-		if ( returnStmt->get_expr() && returnVals.size() == 1 && ! returnVals.front()->get_type()->get_lvalue() ) {
+		if ( returnStmt->get_expr() && returnVals.size() == 1 && ! dynamic_cast< ReferenceType * >( returnVals.front()->get_type() ) ) {
 			// explicitly construct the return value using the return expression and the retVal object
 			assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() );
-			UntypedExpr *construct = new UntypedExpr( new NameExpr( "?{}" ) );
-			construct->get_args().push_back( new AddressExpr( new VariableExpr( returnVals.front() ) ) );
-			construct->get_args().push_back( returnStmt->get_expr() );
-			stmtsToAddBefore.push_back(new ExprStmt(noLabels, construct));
+
+			stmtsToAddBefore.push_back( genCtorDtor( "?{}", dynamic_cast< ObjectDecl *>( returnVals.front() ), returnStmt->get_expr() ) );
 
 			// return the retVal object
@@ -212,4 +210,6 @@
 
 	bool CtorDtor::isManaged( Type * type ) const {
+		// at least for now, references are never constructed
+		if ( dynamic_cast< ReferenceType * >( type ) ) return false;
 		// need to clear and reset qualifiers when determining if a type is managed
 		ValueGuard< Type::Qualifiers > qualifiers( type->get_qualifiers() );
@@ -238,6 +238,7 @@
 			std::list< DeclarationWithType * > & params = GenPoly::getFunctionType( dwt->get_type() )->get_parameters();
 			assert( ! params.empty() );
-			PointerType * type = safe_dynamic_cast< PointerType * >( params.front()->get_type() );
-			managedTypes.insert( SymTab::Mangler::mangle( type->get_base() ) );
+			Type * type = InitTweak::getPointerBase( params.front()->get_type() );
+			assert( type );
+			managedTypes.insert( SymTab::Mangler::mangle( type ) );
 		}
 	}
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/InitTweak/InitTweak.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -380,5 +380,5 @@
 		template<typename CallExpr>
 		Expression *& callArg( CallExpr * callExpr, unsigned int pos ) {
-			if ( pos >= callExpr->get_args().size() ) assertf( false, "asking for argument that doesn't exist. Return NULL/throw exception?" );
+			if ( pos >= callExpr->get_args().size() ) assertf( false, "getCallArg for argument that doesn't exist: (%u); %s.", pos, toString( callExpr ).c_str() );
 			for ( Expression *& arg : callExpr->get_args() ) {
 				if ( pos == 0 ) return arg;
@@ -458,4 +458,6 @@
 		} else if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
 			return arrayType->get_base();
+		} else if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( type ) ) {
+			return refType->get_base();
 		} else {
 			return NULL;
@@ -543,10 +545,9 @@
 		if ( ftype->get_parameters().size() != 2 ) return 0;
 
-		Type * t1 = ftype->get_parameters().front()->get_type();
+		Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() );
 		Type * t2 = ftype->get_parameters().back()->get_type();
-		PointerType * ptrType = dynamic_cast< PointerType * > ( t1 );
-		assert( ptrType );
-
-		if ( ResolvExpr::typesCompatibleIgnoreQualifiers( ptrType->get_base(), t2, SymTab::Indexer() ) ) {
+		assert( t1 );
+
+		if ( ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, SymTab::Indexer() ) ) {
 			return function;
 		} else {
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/Makefile.in	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -221,4 +221,5 @@
 	SynTree/driver_cfa_cpp-PointerType.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-ArrayType.$(OBJEXT) \
+	SynTree/driver_cfa_cpp-ReferenceType.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-FunctionType.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-ReferenceToType.$(OBJEXT) \
@@ -517,6 +518,7 @@
 	SynTree/VoidType.cc SynTree/BasicType.cc \
 	SynTree/PointerType.cc SynTree/ArrayType.cc \
-	SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
-	SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
+	SynTree/ReferenceType.cc SynTree/FunctionType.cc \
+	SynTree/ReferenceToType.cc SynTree/TupleType.cc \
+	SynTree/TypeofType.cc SynTree/AttrType.cc \
 	SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \
 	SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
@@ -864,4 +866,6 @@
 SynTree/driver_cfa_cpp-ArrayType.$(OBJEXT): SynTree/$(am__dirstamp) \
 	SynTree/$(DEPDIR)/$(am__dirstamp)
+SynTree/driver_cfa_cpp-ReferenceType.$(OBJEXT):  \
+	SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
 SynTree/driver_cfa_cpp-FunctionType.$(OBJEXT):  \
 	SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
@@ -1058,4 +1062,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Po@am__quote@
@@ -2154,4 +2159,18 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ArrayType.obj `if test -f 'SynTree/ArrayType.cc'; then $(CYGPATH_W) 'SynTree/ArrayType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ArrayType.cc'; fi`
+
+SynTree/driver_cfa_cpp-ReferenceType.o: SynTree/ReferenceType.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceType.o `test -f 'SynTree/ReferenceType.cc' || echo '$(srcdir)/'`SynTree/ReferenceType.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/ReferenceType.cc' object='SynTree/driver_cfa_cpp-ReferenceType.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ReferenceType.o `test -f 'SynTree/ReferenceType.cc' || echo '$(srcdir)/'`SynTree/ReferenceType.cc
+
+SynTree/driver_cfa_cpp-ReferenceType.obj: SynTree/ReferenceType.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceType.obj `if test -f 'SynTree/ReferenceType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceType.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/ReferenceType.cc' object='SynTree/driver_cfa_cpp-ReferenceType.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ReferenceType.obj `if test -f 'SynTree/ReferenceType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceType.cc'; fi`
 
 SynTree/driver_cfa_cpp-FunctionType.o: SynTree/FunctionType.cc
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/Parser/DeclarationNode.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -329,7 +329,7 @@
 } // DeclarationNode::newTypeDecl
 
-DeclarationNode * DeclarationNode::newPointer( DeclarationNode * qualifiers ) {
-	DeclarationNode * newnode = new DeclarationNode;
-	newnode->type = new TypeData( TypeData::Pointer );
+DeclarationNode * DeclarationNode::newPointer( DeclarationNode * qualifiers, OperKinds kind ) {
+	DeclarationNode * newnode = new DeclarationNode;
+	newnode->type = new TypeData( kind == OperKinds::PointTo ? TypeData::Pointer : TypeData::Reference );
 	if ( qualifiers ) {
 		return newnode->addQualifiers( qualifiers );
@@ -748,5 +748,5 @@
 DeclarationNode * DeclarationNode::addPointer( DeclarationNode * p ) {
 	if ( p ) {
-		assert( p->type->kind == TypeData::Pointer );
+		assert( p->type->kind == TypeData::Pointer || TypeData::Reference );
 		setBase( p->type );
 		p->type = nullptr;
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/Parser/ExpressionNode.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -296,5 +296,5 @@
 Expression *build_unary_ptr( OperKinds op, ExpressionNode *expr_node ) {
 	std::list< Expression * > args;
-	args.push_back( new AddressExpr( maybeMoveBuild< Expression >(expr_node) ) );
+	args.push_back(  maybeMoveBuild< Expression >(expr_node) ); // xxx
 	return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
 }
@@ -307,5 +307,5 @@
 Expression *build_binary_ptr( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
 	std::list< Expression * > args;
-	args.push_back( new AddressExpr( maybeMoveBuild< Expression >(expr_node1) ) );
+	args.push_back( maybeMoveBuild< Expression >(expr_node1) );
 	args.push_back( maybeMoveBuild< Expression >(expr_node2) );
 	return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/Parser/ParseNode.h	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -237,5 +237,5 @@
 	static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
 	static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
-	static DeclarationNode * newPointer( DeclarationNode * qualifiers );
+	static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
 	static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
 	static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/Parser/TypeData.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -30,4 +30,5 @@
 	  case Unknown:
 	  case Pointer:
+	  case Reference:
 	  case EnumConstant:
 		// nothing else to initialize
@@ -99,4 +100,5 @@
 	  case Unknown:
 	  case Pointer:
+	  case Reference:
 	  case EnumConstant:
 		// nothing to destroy
@@ -165,4 +167,5 @@
 	  case EnumConstant:
 	  case Pointer:
+	  case Reference:
 		// nothing else to copy
 		break;
@@ -398,10 +401,10 @@
 			// add dtor:  void ^?{}(T *)
 			FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
-			dtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
+			dtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
 			td->get_assertions().push_front( new FunctionDecl( "^?{}", Type::StorageClasses(), LinkageSpec::Cforall, dtorType, nullptr ) );
 
 			// add copy ctor:  void ?{}(T *, T)
 			FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
-			copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
+			copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
 			copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
 			td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, copyCtorType, nullptr ) );
@@ -409,10 +412,10 @@
 			// add default ctor:  void ?{}(T *)
 			FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
-			ctorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
+			ctorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
 			td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, ctorType, nullptr ) );
 
 			// add assignment operator:  T * ?=?(T *, T)
 			FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
-			assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
+			assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
 			assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
 			assignType->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
@@ -434,4 +437,6 @@
 	  case TypeData::Array:
 		return buildArray( td );
+	  case TypeData::Reference:
+		return buildReference( td );
 	  case TypeData::Function:
 		return buildFunction( td );
@@ -612,5 +617,16 @@
 	buildForall( td->forall, at->get_forall() );
 	return at;
-} // buildPointer
+} // buildArray
+
+ReferenceType * buildReference( const TypeData * td ) {
+	ReferenceType * rt;
+	if ( td->base ) {
+		rt = new ReferenceType( buildQualifiers( td ), typebuild( td->base ) );
+	} else {
+		rt = new ReferenceType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
+	} // if
+	buildForall( td->forall, rt->get_forall() );
+	return rt;
+} // buildReference
 
 AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
Index: src/Parser/TypeData.h
===================================================================
--- src/Parser/TypeData.h	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/Parser/TypeData.h	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -21,5 +21,5 @@
 
 struct TypeData {
-	enum Kind { Basic, Pointer, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
+	enum Kind { Basic, Pointer, Array, Reference, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
 				SymbolicInst, Tuple, Typeof, Builtin, Unknown };
 
@@ -101,4 +101,5 @@
 PointerType * buildPointer( const TypeData * );
 ArrayType * buildArray( const TypeData * );
+ReferenceType * buildReference( const TypeData * );
 AggregateDecl * buildAggregate( const TypeData *, std::list< Attribute * > );
 ReferenceToType * buildComAggInst( const TypeData *, std::list< Attribute * > attributes, LinkageSpec::Spec linkage );
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/Parser/parser.yy	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -666,5 +666,5 @@
 	conditional_expression
 	| unary_expression assignment_operator assignment_expression
-		{ $$ = new ExpressionNode( build_binary_ptr( $2, $1, $3 ) ); }
+		{ $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); }
 	;
 
@@ -2401,7 +2401,7 @@
 variable_ptr:
 	ptrref_operator variable_declarator
-		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| ptrref_operator type_qualifier_list variable_declarator
-		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
 	| '(' variable_ptr ')' attribute_list_opt
 		{ $$ = $2->addQualifiers( $4 ); }				// redundant parenthesis
@@ -2449,7 +2449,7 @@
 function_ptr:
 	ptrref_operator function_declarator
-		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| ptrref_operator type_qualifier_list function_declarator
-		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
 	| '(' function_ptr ')'
 		{ $$ = $2; }
@@ -2489,7 +2489,7 @@
 KR_function_ptr:
 	ptrref_operator KR_function_declarator
-		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| ptrref_operator type_qualifier_list KR_function_declarator
-		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
 	| '(' KR_function_ptr ')'
 		{ $$ = $2; }
@@ -2533,7 +2533,7 @@
 type_ptr:
 	ptrref_operator variable_type_redeclarator
-		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| ptrref_operator type_qualifier_list variable_type_redeclarator
-		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
 	| '(' type_ptr ')' attribute_list_opt
 		{ $$ = $2->addQualifiers( $4 ); }
@@ -2577,7 +2577,7 @@
 identifier_parameter_ptr:
 	ptrref_operator identifier_parameter_declarator
-		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| ptrref_operator type_qualifier_list identifier_parameter_declarator
-		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
 	| '(' identifier_parameter_ptr ')' attribute_list_opt
 		{ $$ = $2->addQualifiers( $4 ); }
@@ -2637,7 +2637,7 @@
 type_parameter_ptr:
 	ptrref_operator type_parameter_redeclarator
-		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| ptrref_operator type_qualifier_list type_parameter_redeclarator
-		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
 	| '(' type_parameter_ptr ')' attribute_list_opt
 		{ $$ = $2->addQualifiers( $4 ); }
@@ -2680,11 +2680,11 @@
 abstract_ptr:
 	ptrref_operator
-		{ $$ = DeclarationNode::newPointer( 0 ); }
+		{ $$ = DeclarationNode::newPointer( 0, $1 ); }
 	| ptrref_operator type_qualifier_list
-		{ $$ = DeclarationNode::newPointer( $2 ); }
+		{ $$ = DeclarationNode::newPointer( $2, $1 ); }
 	| ptrref_operator abstract_declarator
-		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| ptrref_operator type_qualifier_list abstract_declarator
-		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
 	| '(' abstract_ptr ')' attribute_list_opt
 		{ $$ = $2->addQualifiers( $4 ); }
@@ -2769,11 +2769,11 @@
 abstract_parameter_ptr:
 	ptrref_operator
-		{ $$ = DeclarationNode::newPointer( nullptr ); }
+		{ $$ = DeclarationNode::newPointer( nullptr, $1 ); }
 	| ptrref_operator type_qualifier_list
-		{ $$ = DeclarationNode::newPointer( $2 ); }
+		{ $$ = DeclarationNode::newPointer( $2, $1 ); }
 	| ptrref_operator abstract_parameter_declarator
-		{ $$ = $2->addPointer( DeclarationNode::newPointer( nullptr ) ); }
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
 	| ptrref_operator type_qualifier_list abstract_parameter_declarator
-		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
 	| '(' abstract_parameter_ptr ')' attribute_list_opt
 		{ $$ = $2->addQualifiers( $4 ); }
@@ -2848,11 +2848,11 @@
 variable_abstract_ptr:
 	ptrref_operator
-		{ $$ = DeclarationNode::newPointer( 0 ); }
+		{ $$ = DeclarationNode::newPointer( 0, $1 ); }
 	| ptrref_operator type_qualifier_list
-		{ $$ = DeclarationNode::newPointer( $2 ); }
+		{ $$ = DeclarationNode::newPointer( $2, $1 ); }
 	| ptrref_operator variable_abstract_declarator
-		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| ptrref_operator type_qualifier_list variable_abstract_declarator
-		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
 	| '(' variable_abstract_ptr ')' attribute_list_opt
 		{ $$ = $2->addQualifiers( $4 ); }
@@ -2894,15 +2894,15 @@
 		// No SUE declaration in parameter list.
 	ptrref_operator type_specifier_nobody
-		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| type_qualifier_list ptrref_operator type_specifier_nobody
-		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
 	| ptrref_operator cfa_abstract_function
-		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| type_qualifier_list ptrref_operator cfa_abstract_function
-		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
 	| ptrref_operator cfa_identifier_parameter_declarator_tuple
-		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple
-		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
 	;
 
@@ -2982,15 +2982,15 @@
 cfa_abstract_ptr:										// CFA
 	ptrref_operator type_specifier
-		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| type_qualifier_list ptrref_operator type_specifier
-		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
 	| ptrref_operator cfa_abstract_function
-		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| type_qualifier_list ptrref_operator cfa_abstract_function
-		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
 	| ptrref_operator cfa_abstract_declarator_tuple
-		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
 	| type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple
-		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
 	;
 
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -305,4 +305,7 @@
 				std::cerr << std::endl << " to ";
 				formalType->print( std::cerr, 8 );
+				std::cerr << std::endl << "environment is: ";
+				alt.env.print( std::cerr, 8 );
+				std::cerr << std::endl;
 			)
 			Cost newCost = conversionCost( actualType, formalType, indexer, alt.env );
@@ -400,4 +403,5 @@
 			Expression * actual = actualIt->expr;
 			Type * actualType = actual->get_result();
+
 			PRINT(
 				std::cerr << "formal type is ";
@@ -643,4 +647,5 @@
 			makeExprList( instantiatedActuals, appExpr->get_args() );
 			PRINT(
+				std::cerr << "instantiate function success: " << appExpr << std::endl;
 				std::cerr << "need assertions:" << std::endl;
 				printAssertionSet( resultNeed, std::cerr, 8 );
@@ -753,5 +758,5 @@
 				PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
 				FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
-				std::cerr << "Case +++++++++++++" << std::endl;
+				std::cerr << "Case +++++++++++++ " << appExpr->get_function() << std::endl;
 				std::cerr << "formals are:" << std::endl;
 				printAll( function->get_parameters(), std::cerr, 8 );
@@ -796,5 +801,5 @@
 	bool isLvalue( Expression *expr ) {
 		// xxx - recurse into tuples?
-		return expr->has_result() && expr->get_result()->get_lvalue();
+		return expr->has_result() && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
 	}
 
@@ -882,10 +887,19 @@
 		funcFinder.findWithAdjustment( memberExpr->get_aggregate() );
 		for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
-			if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) {
-				addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
-			} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) {
-				addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
-			} else if ( TupleType * tupleType = dynamic_cast< TupleType * >( agg->expr->get_result() ) ) {
-				addTupleMembers( tupleType, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
+			// it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value
+			std::unique_ptr<Expression> aggrExpr( agg->expr->clone() );
+			Type * aggrType = aggrExpr->get_result();
+			if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
+				aggrType = aggrType->stripReferences();
+				aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );
+			}
+
+			// find member of the given type
+			if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
+				addAggMembers( structInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
+			} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
+				addAggMembers( unionInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
+			} else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
+				addTupleMembers( tupleType, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
 			} // if
 		} // for
Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/ResolvExpr/CastCost.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -54,4 +54,6 @@
 		} else if ( dynamic_cast< VoidType* >( dest ) ) {
 			return Cost( 0, 0, 1 );
+		} else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
+			return convertToReferenceCost( src, refType, indexer, env );
 		} else {
 			CastCost converter( dest, indexer, env );
@@ -76,5 +78,5 @@
 			cost = Cost( 1, 0, 0 );
 		} else {
-			ConversionCost::visit( basicType );
+			cost = conversionCost( basicType, dest, indexer, env );
 		} // if
 	}
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/ResolvExpr/CommonType.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -17,5 +17,4 @@
 #include "SynTree/Type.h"
 #include "Unify.h"
-
 
 /// #define DEBUG
@@ -31,4 +30,5 @@
 		virtual void visit( PointerType *pointerType );
 		virtual void visit( ArrayType *arrayType );
+		virtual void visit( ReferenceType *refType );
 		virtual void visit( FunctionType *functionType );
 		virtual void visit( StructInstType *aggregateUseType );
@@ -42,5 +42,6 @@
 		virtual void visit( OneType *oneType );
 
-		void getCommonWithVoidPointer( PointerType* voidPointer, PointerType* otherPointer );
+		template< typename Pointer > void getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer );
+		template< typename RefType > void handleRefType( RefType *inst, Type *other );
 
 		Type *result;
@@ -52,6 +53,43 @@
 	};
 
+	Type * handleReference( ReferenceType * refType, Type * other, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment & env, const OpenVarSet &openVars ) {
+		Type * result = nullptr, * common = nullptr;
+		AssertionSet have, need;
+		OpenVarSet newOpen( openVars );
+		// need unify to bind type variables
+		if ( unify( refType->get_base(), other, env, have, need, newOpen, indexer, common ) ) {
+			// std::cerr << "unify success" << std::endl;
+			if ( widenSecond ) {
+				if ( widenFirst || other->get_qualifiers() <= refType->get_qualifiers() ) {
+					result = new ReferenceType( refType->get_qualifiers(), common ); // refType->clone();
+					result->get_qualifiers() |= other->get_qualifiers();
+				}
+			} else if ( widenFirst ) {
+				if ( widenSecond || refType->get_qualifiers() <= other->get_qualifiers() ) {
+					result = common;
+					result->get_qualifiers() |= refType->get_qualifiers();
+				}
+			}
+		} else {
+			// std::cerr << "exact unify failed: " << refType << " " << other << std::endl;
+		}
+		// std::cerr << "common type of reference [" << refType << "] and non-reference [" << other << "] is [" << result << "]" << std::endl;
+		return result;
+	}
+
 	Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
 		CommonType visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
+
+		ReferenceType * refType1 = dynamic_cast< ReferenceType * >( type1 );
+		ReferenceType * refType2 = dynamic_cast< ReferenceType * >( type2 );
+		if ( (refType1 || refType2) && (! refType1 || ! refType2) ) {
+			// handle the case where exactly one of the types is a reference type specially
+			if ( refType1 ) {
+				return handleReference( refType1, type2, widenFirst, widenSecond, indexer, env, openVars );
+			} else if ( refType2 ) {
+				return handleReference( refType2, type1, widenSecond, widenFirst, indexer, env, openVars );
+			}
+		}
+
 		type1->accept( visitor );
 		Type *result = visitor.get_result();
@@ -142,5 +180,6 @@
 	}
 
-	void CommonType::getCommonWithVoidPointer( PointerType* voidPointer, PointerType* otherPointer ) {
+	template< typename Pointer >
+	void CommonType::getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ) {
 		if ( TypeInstType* var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) {
 			OpenVarSet::const_iterator entry = openVars.find( var->get_name() );
@@ -188,4 +227,37 @@
 
 	void CommonType::visit( __attribute((unused)) ArrayType *arrayType ) {}
+
+	void CommonType::visit( ReferenceType *refType ) {
+		if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
+			if ( widenFirst && dynamic_cast< VoidType* >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {
+				getCommonWithVoidPointer( otherRef, refType );
+			} else if ( widenSecond && dynamic_cast< VoidType* >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {
+				getCommonWithVoidPointer( refType, otherRef );
+			} else if ( ( refType->get_base()->get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst )
+					   && ( refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers() || widenSecond ) ) {
+				Type::Qualifiers tq1 = refType->get_base()->get_qualifiers(), tq2 = otherRef->get_base()->get_qualifiers();
+				refType->get_base()->get_qualifiers() = Type::Qualifiers();
+				otherRef->get_base()->get_qualifiers() = Type::Qualifiers();
+				AssertionSet have, need;
+				OpenVarSet newOpen( openVars );
+				if ( unifyExact( refType->get_base(), otherRef->get_base(), env, have, need, newOpen, indexer ) ) {
+					if ( tq1 < tq2 ) {
+						result = refType->clone();
+					} else {
+						result = otherRef->clone();
+					} // if
+					result->get_qualifiers() = tq1 | tq2;
+				} else {
+					/// std::cout << "place for ptr-to-type" << std::endl;
+				} // if
+				refType->get_base()->get_qualifiers() = tq1;
+				otherRef->get_base()->get_qualifiers() = tq2;
+			} // if
+		} else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
+			result = refType->clone();
+			result->get_qualifiers() |= type2->get_qualifiers();
+		} // if
+	}
+
 	void CommonType::visit( __attribute((unused)) FunctionType *functionType ) {}
 	void CommonType::visit( __attribute((unused)) StructInstType *aggregateUseType ) {}
@@ -195,8 +267,7 @@
 		if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
 			// reuse BasicType, EnumInstType code by swapping type2 with enumInstType
-			Type * temp = type2;
+			ValueGuard< Type * > temp( type2 );
 			type2 = enumInstType;
-			temp->accept( *this );
-			type2 = temp;
+			temp.old->accept( *this );
 		} // if
 	}
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/ResolvExpr/ConversionCost.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -57,4 +57,7 @@
 		} else if ( dynamic_cast< VoidType* >( dest ) ) {
 			return Cost( 0, 0, 1 );
+		} else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
+			// std::cerr << "conversionCost: dest is reference" << std::endl;
+			return convertToReferenceCost( src, refType, indexer, env );
 		} else {
 			ConversionCost converter( dest, indexer, env );
@@ -66,4 +69,45 @@
 			} // if
 		} // if
+	}
+
+	Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
+		// std::cerr << "convert to reference cost..." << std::endl;
+		if ( ReferenceType *srcAsRef = dynamic_cast< ReferenceType * >( src ) ) { // pointer-like conversions between references
+			// std::cerr << "converting between references" << std::endl;
+			if ( srcAsRef->get_base()->get_qualifiers() <= dest->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), dest->get_base(), indexer, env ) ) {
+				return Cost( 0, 0, 1 );
+			} else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
+				int assignResult = ptrsAssignable( srcAsRef->get_base(), dest->get_base(), env );
+				if ( assignResult < 0 ) {
+					return Cost( 0, 0, 1 );
+				} else if ( assignResult > 0 ) {
+					return Cost( 1, 0, 0 );
+				} // if
+			} // if
+		} else if ( typesCompatibleIgnoreQualifiers( src, dest->get_base(), indexer, env ) ) {
+			// std::cerr << "converting compatible base type" << std::endl;
+			if ( src->get_lvalue() ) {
+				// std::cerr << "lvalue to reference conversion" << std::endl;
+				// lvalue-to-reference conversion:  cv lvalue T => cv T &
+				if ( src->get_qualifiers() == dest->get_base()->get_qualifiers() ) {
+					return Cost( 0, 0, 1 ); // cost needs to be non-zero to add cast
+				} if ( src->get_qualifiers() < dest->get_base()->get_qualifiers() ) {
+					return Cost( 0, 0, 2 ); // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
+				} else {
+					return Cost( 1, 0, 0 );
+				}
+			} else if ( dest->get_base()->get_const() ) {
+				// std::cerr << "rvalue to const ref conversion" << std::endl;
+				// rvalue-to-const-reference conversion: T => const T &
+				return Cost( 0, 0, 1 );
+			} else {
+				// std::cerr << "rvalue to non-const reference conversion" << std::endl;
+				// rvalue-to-reference conversion: T => T &
+				return Cost( 1, 0, 0 );
+			}
+		} else {
+			// std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl;
+		}
+		return Cost::infinity;
 	}
 
@@ -173,5 +217,5 @@
 			if ( pointerType->get_base()->get_qualifiers() <= destAsPtr->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
 				cost = Cost( 0, 0, 1 );
-			} else {
+			} else {  // xxx - this discards pointer qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
 				int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env );
 				if ( assignResult < 0 ) {
@@ -187,4 +231,14 @@
 
 	void ConversionCost::visit(__attribute((unused)) ArrayType *arrayType) {}
+
+	void ConversionCost::visit(ReferenceType *refType) {
+		// Note: dest can never be a reference, since it would have been caught in an earlier check
+		assert( ! dynamic_cast< ReferenceType * >( dest ) );
+		// convert reference to rvalue: cv T1 & => T2
+		// recursively compute conversion cost from T1 to T2.
+		// cv can be safely dropped because of 'implicit dereference' behavior.
+		refType->get_base()->accept( *this );
+	}
+
 	void ConversionCost::visit(__attribute((unused)) FunctionType *functionType) {}
 
@@ -208,5 +262,5 @@
 		static Type::Qualifiers q;
 		static BasicType integer( q, BasicType::SignedInt );
-		integer.accept( *this );
+		integer.accept( *this );  // safe if dest >= int
 		if ( cost < Cost( 1, 0, 0 ) ) {
 			cost.incSafe();
Index: src/ResolvExpr/ConversionCost.h
===================================================================
--- src/ResolvExpr/ConversionCost.h	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/ResolvExpr/ConversionCost.h	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ConversionCost.h -- 
+// ConversionCost.h --
 //
 // Author           : Richard C. Bilson
@@ -26,5 +26,5 @@
 	  public:
 		ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
-  
+
 		Cost get_cost() const { return cost; }
 
@@ -33,4 +33,5 @@
 		virtual void visit(PointerType *pointerType);
 		virtual void visit(ArrayType *arrayType);
+		virtual void visit(ReferenceType *refType);
 		virtual void visit(FunctionType *functionType);
 		virtual void visit(StructInstType *aggregateUseType);
@@ -49,4 +50,6 @@
 		const TypeEnvironment &env;
 	};
+
+	Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/ResolvExpr/Unify.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -42,4 +42,5 @@
 		virtual void visit(PointerType *pointerType);
 		virtual void visit(ArrayType *arrayType);
+		virtual void visit(ReferenceType *refType);
 		virtual void visit(FunctionType *functionType);
 		virtual void visit(StructInstType *aggregateUseType);
@@ -428,4 +429,12 @@
 	}
 
+	void Unify::visit(ReferenceType *refType) {
+		if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
+			result = unifyExact( refType->get_base(), otherRef->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+			markAssertions( haveAssertions, needAssertions, refType );
+			markAssertions( haveAssertions, needAssertions, otherRef );
+		} // if
+	}
+
 	void Unify::visit(ArrayType *arrayType) {
 		ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SymTab/Autogen.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -125,5 +125,5 @@
 	FunctionType * genDefaultType( Type * paramType ) {
 		FunctionType *ftype = new FunctionType( Type::Qualifiers(), false );
-		ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), paramType->clone() ), nullptr );
+		ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr );
 		ftype->get_parameters().push_back( dstParam );
 
@@ -176,5 +176,6 @@
 			FunctionType * ftype = funcDecl->get_functionType();
 			assert( ! ftype->get_parameters().empty() );
-			Type * t = safe_dynamic_cast< PointerType * >( ftype->get_parameters().front()->get_type() )->get_base();
+			Type * t = InitTweak::getPointerBase( ftype->get_parameters().front()->get_type() );
+			assert( t );
 			map.insert( Mangler::mangleType( t ), true );
 		}
@@ -297,21 +298,9 @@
 	/// generates a single struct member operation (constructor call, destructor call, assignment call)
 	void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool isDynamicLayout, bool forward = true ) {
-		ObjectDecl * returnVal = NULL;
-		if ( ! func->get_functionType()->get_returnVals().empty() ) {
-			returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() );
-		}
-
 		InitTweak::InitExpander srcParam( src );
 
-		// assign to destination (and return value if generic)
-		UntypedExpr *derefExpr = UntypedExpr::createDeref( new VariableExpr( dstParam ) );
-		Expression *dstselect = new MemberExpr( field, derefExpr );
+		// assign to destination
+		Expression *dstselect = new MemberExpr( field, new CastExpr( new VariableExpr( dstParam ), safe_dynamic_cast< ReferenceType* >( dstParam->get_type() )->get_base()->clone() ) );
 		genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
-
-		if ( isDynamicLayout && returnVal ) {
-			// xxx - there used to be a dereference on returnVal, but this seems to have been wrong?
-			Expression *retselect = new MemberExpr( field, new VariableExpr( returnVal ) );
-			genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
-		} // if
 	}
 
@@ -467,7 +456,5 @@
 					// 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.
+					// figure out whether it's valid/choose the correct unnamed member
 					continue;
 				}
@@ -485,5 +472,5 @@
 	void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) {
 		UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
-		copy->get_args().push_back( new VariableExpr( dstParam ) );
+		copy->get_args().push_back( new AddressExpr( new VariableExpr( dstParam ) ) );
 		copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
 		copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) );
@@ -497,11 +484,8 @@
 		ObjectDecl * dstParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() );
 		ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() );
-		ObjectDecl * returnVal = nullptr;
-		if ( ! ftype->get_returnVals().empty() ) {
-			returnVal = safe_dynamic_cast< ObjectDecl * >( ftype->get_returnVals().front() );
-		}
 
 		makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) );
-		if ( returnVal ) {
+		if ( InitTweak::isAssignment( funcDecl->get_name() ) ) {
+			// also generate return statement in assignment
 			funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
 		}
@@ -512,5 +496,5 @@
 		// Make function polymorphic in same parameters as generic union, if applicable
 		const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
-		
+
 		// default ctor/dtor need only first parameter
 		// void ?{}(T *); void ^?{}(T *);
Index: src/SymTab/Autogen.h
===================================================================
--- src/SymTab/Autogen.h	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SymTab/Autogen.h	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -43,35 +43,33 @@
 	template< typename OutputIterator >
 	Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
-	// want to be able to generate assignment, ctor, and dtor generically,
-	// so fname is either ?=?, ?{}, or ^?{}
-	UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
+		// want to be able to generate assignment, ctor, and dtor generically,
+		// so fname is either ?=?, ?{}, or ^?{}
+		UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
 
-	// do something special for unnamed members
-	dstParam = new AddressExpr( dstParam );
-	if ( addCast ) {
-		// cast to T* with qualifiers removed, so that qualified objects can be constructed
-		// and destructed with the same functions as non-qualified objects.
-		// unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
-		// must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
-		// remove lvalue as a qualifier, this can change to
-		//   type->get_qualifiers() = Type::Qualifiers();
-		assert( type );
-		Type * castType = type->clone();
-		castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
-		castType->set_lvalue( true ); // xxx - might not need this
-		dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
-	}
-	fExpr->get_args().push_back( dstParam );
+		if ( addCast ) {
+			// cast to T& with qualifiers removed, so that qualified objects can be constructed
+			// and destructed with the same functions as non-qualified objects.
+			// unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
+			// must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
+			// remove lvalue as a qualifier, this can change to
+			//   type->get_qualifiers() = Type::Qualifiers();
+			assert( type );
+			Type * castType = type->clone();
+			castType->get_qualifiers() -= Type::Qualifiers( Type::Lvalue | Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
+			// castType->set_lvalue( true ); // xxx - might not need this
+			dstParam = new CastExpr( dstParam, new ReferenceType( Type::Qualifiers(), castType ) );
+		}
+		fExpr->get_args().push_back( dstParam );
 
-	Statement * listInit = srcParam.buildListInit( fExpr );
+		Statement * listInit = srcParam.buildListInit( fExpr );
 
-	std::list< Expression * > args = *++srcParam;
-	fExpr->get_args().splice( fExpr->get_args().end(), args );
+		std::list< Expression * > args = *++srcParam;
+		fExpr->get_args().splice( fExpr->get_args().end(), args );
 
-	*out++ = new ExprStmt( noLabels, fExpr );
+		*out++ = new ExprStmt( noLabels, fExpr );
 
-	srcParam.clearArrayIndices();
+		srcParam.clearArrayIndices();
 
-	return listInit;
+		return listInit;
 	}
 
@@ -109,5 +107,5 @@
 
 		UntypedExpr *inc = new UntypedExpr( update );
-		inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+		inc->get_args().push_back( new VariableExpr( index ) );
 
 		UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SymTab/Indexer.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -158,5 +158,6 @@
 				assert( ! params.empty() );
 				// use base type of pointer, so that qualifiers on the pointer type aren't considered.
-				Type * base = safe_dynamic_cast< PointerType * >( params.front()->get_type() )->get_base();
+				Type * base = InitTweak::getPointerBase( params.front()->get_type() );
+				assert( base );
 				funcMap[ Mangler::mangle( base ) ] += function;
 			} else {
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SymTab/Validate.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -823,7 +823,7 @@
 				throw SemanticError( "Constructors, destructors, and assignment functions require at least one parameter ", funcDecl );
 			}
-			PointerType * ptrType = dynamic_cast< PointerType * >( params.front()->get_type() );
-			if ( ! ptrType || ptrType->is_array() ) {
-				throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a pointer ", funcDecl );
+			ReferenceType * refType = dynamic_cast< ReferenceType * >( params.front()->get_type() );
+			if ( ! refType ) {
+				throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a reference ", funcDecl );
 			}
 			if ( InitTweak::isCtorDtor( funcDecl->get_name() ) && returnVals.size() != 0 ) {
Index: src/SynTree/AddressExpr.cc
===================================================================
--- src/SynTree/AddressExpr.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SynTree/AddressExpr.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -18,7 +18,35 @@
 #include "Common/utility.h"
 
+// Address expressions are typed based on the following inference rules:
+//    E : lvalue T  &..& (n references)
+//   &E :        T *&..& (n references)
+//
+//    E : T  &..&        (m references)
+//   &E : T *&..&        (m-1 references)
+//
+// That is, lvalues becomes
+
+namespace {
+	Type * addrType( Type * type ) {
+		if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( type ) ) {
+			return new ReferenceType( refType->get_qualifiers(), addrType( refType->get_base() ) );
+		} else {
+			return new PointerType( Type::Qualifiers(), type->clone() );
+		}
+	}
+}
+
 AddressExpr::AddressExpr( Expression *arg, Expression *_aname ) : Expression( _aname ), arg( arg ) {
 	if ( arg->has_result() ) {
-		set_result( new PointerType( Type::Qualifiers(), arg->get_result()->clone() ) );
+		if ( arg->get_result()->get_lvalue() ) {
+			// lvalue, retains all layers of reference and gains a pointer inside the references
+			set_result( addrType( arg->get_result() ) );
+		} else {
+			// taking address of non-lvalue -- must be a reference, loses one layer of reference
+			ReferenceType * refType = safe_dynamic_cast< ReferenceType * >( arg->get_result() );
+			set_result( addrType( refType->get_base() ) );
+		}
+		// result of & is never an lvalue
+		get_result()->set_lvalue( false );
 	}
 }
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SynTree/Expression.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -335,5 +335,7 @@
 namespace {
 	TypeSubstitution makeSub( Type * t ) {
-		if ( StructInstType * aggInst = dynamic_cast< StructInstType * >( t ) ) {
+		if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( t ) ) {
+			return makeSub( refType->get_base() );
+		} else if ( StructInstType * aggInst = dynamic_cast< StructInstType * >( t ) ) {
 			return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->get_parameters().begin() );
 		} else if ( UnionInstType * aggInst = dynamic_cast< UnionInstType * >( t ) ) {
@@ -400,9 +402,6 @@
 	if ( Type * type = expr->get_result() ) {
 		Type * base = InitTweak::getPointerBase( type );
-		if ( ! base ) {
-			std::cerr << type << std::endl;
-		}
-		assertf( base, "expected pointer type in dereference\n" );
-		ret->set_result( maybeClone( base ) );
+		assertf( base, "expected pointer type in dereference (type was %s)", toString( type ).c_str() );
+		ret->set_result( new ReferenceType( Type::Qualifiers(), base->clone() ) );
 	}
 	return ret;
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SynTree/Mutator.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -473,4 +473,10 @@
 }
 
+Type *Mutator::mutate( ReferenceType *refType ) {
+	mutateAll( refType->get_forall(), *this );
+	refType->set_base( maybeMutate( refType->get_base(), *this ) );
+	return refType;
+}
+
 Type *Mutator::mutate( FunctionType *functionType ) {
 	mutateAll( functionType->get_forall(), *this );
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SynTree/Mutator.h	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -92,4 +92,5 @@
 	virtual Type* mutate( PointerType *pointerType );
 	virtual Type* mutate( ArrayType *arrayType );
+	virtual Type* mutate( ReferenceType *refType );
 	virtual Type* mutate( FunctionType *functionType );
 	virtual Type* mutate( StructInstType *aggregateUseType );
Index: src/SynTree/ReferenceType.cc
===================================================================
--- src/SynTree/ReferenceType.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
+++ src/SynTree/ReferenceType.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -0,0 +1,44 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// PointerType.cc --
+//
+// Author           : Rob Schluntz
+// Created On       : Fri May 12 18:12:15 2017
+// Last Modified By : Rob Schluntz
+// Last Modified On : Fri May 12 18:12:15 2017
+// Update Count     : 1
+//
+
+#include "Type.h"
+#include "Expression.h"
+#include "Common/utility.h"
+
+ReferenceType::ReferenceType( const Type::Qualifiers &tq, Type *base, const std::list< Attribute * > & attributes )
+  : Type( tq, attributes ), base( base ) {
+}
+
+ReferenceType::ReferenceType( const ReferenceType &other )
+  : Type( other ), base( maybeClone( other.base ) ) {
+}
+
+ReferenceType::~ReferenceType() {
+  delete base;
+}
+
+void ReferenceType::print( std::ostream &os, int indent ) const {
+  Type::print( os, indent );
+  os << "reference to ";
+  if ( base ) {
+    base->print( os, indent );
+  } // if
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SynTree/SynTree.h	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -101,4 +101,5 @@
 class PointerType;
 class ArrayType;
+class ReferenceType;
 class FunctionType;
 class ReferenceToType;
Index: src/SynTree/Type.cc
===================================================================
--- src/SynTree/Type.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SynTree/Type.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -65,8 +65,16 @@
 const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic" };
 
-Type *Type::stripDeclarator() {
+Type * Type::stripDeclarator() {
 	Type * type = this;
 	while ( Type * at = InitTweak::getPointerBase( type ) ) {
 		type = at;
+	}
+	return type;
+}
+
+Type * Type::stripReferences() {
+	Type * type = this;
+	while ( ReferenceType * ref = dynamic_cast<ReferenceType *>( type ) ) {
+		type = ref->get_base();
 	}
 	return type;
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SynTree/Type.h	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -158,5 +158,8 @@
 
 	/// return type without outer pointers and arrays
-	Type *stripDeclarator();
+	Type * stripDeclarator();
+
+	/// return type without outer references
+	Type * stripReferences();
 
 	virtual bool isComplete() const { return true; }
@@ -249,4 +252,6 @@
 	bool is_array() const { return isStatic || isVarLen || dimension; }
 
+	virtual bool isComplete() const { return ! isVarLen; }
+
 	virtual PointerType *clone() const { return new PointerType( *this ); }
 	virtual void accept( Visitor & v ) { v.visit( this ); }
@@ -290,4 +295,21 @@
 };
 
+class ReferenceType : public Type {
+public:
+	ReferenceType( const Type::Qualifiers & tq, Type *base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
+	ReferenceType( const ReferenceType & );
+	virtual ~ReferenceType();
+
+	Type *get_base() { return base; }
+	void set_base( Type *newValue ) { base = newValue; }
+
+	virtual ReferenceType *clone() const { return new ReferenceType( *this ); }
+	virtual void accept( Visitor & v ) { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const;
+private:
+	Type *base;
+};
+
 class FunctionType : public Type {
   public:
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SynTree/Visitor.cc	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -363,4 +363,5 @@
 void Visitor::visit( PointerType *pointerType ) {
 	acceptAll( pointerType->get_forall(), *this );
+	// xxx - should PointerType visit/mutate dimension?
 	maybeAccept( pointerType->get_base(), *this );
 }
@@ -370,4 +371,9 @@
 	maybeAccept( arrayType->get_dimension(), *this );
 	maybeAccept( arrayType->get_base(), *this );
+}
+
+void Visitor::visit( ReferenceType *refType ) {
+	acceptAll( refType->get_forall(), *this );
+	maybeAccept( refType->get_base(), *this );
 }
 
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SynTree/Visitor.h	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -95,4 +95,5 @@
 	virtual void visit( PointerType *pointerType );
 	virtual void visit( ArrayType *arrayType );
+	virtual void visit( ReferenceType *refType );
 	virtual void visit( FunctionType *functionType );
 	virtual void visit( StructInstType *aggregateUseType );
Index: src/SynTree/module.mk
===================================================================
--- src/SynTree/module.mk	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/SynTree/module.mk	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -20,4 +20,5 @@
        SynTree/PointerType.cc \
        SynTree/ArrayType.cc \
+       SynTree/ReferenceType.cc \
        SynTree/FunctionType.cc \
        SynTree/ReferenceToType.cc \
Index: src/libcfa/containers/maybe
===================================================================
--- src/libcfa/containers/maybe	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/libcfa/containers/maybe	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -29,17 +29,17 @@
 
 forall(otype T)
-void ?{}(maybe(T) * this);
+void ?{}(maybe(T) & this);
 
 forall(otype T)
-void ?{}(maybe(T) * this, T value);
+void ?{}(maybe(T) & this, T value);
 
 forall(otype T)
-void ?{}(maybe(T) * this, maybe(T) other);
+void ?{}(maybe(T) & this, maybe(T) other);
 
 forall(otype T)
-void ^?{}(maybe(T) * this);
+void ^?{}(maybe(T) & this);
 
 forall(otype T)
-maybe(T) ?=?(maybe(T) * this, maybe(T) other);
+maybe(T) ?=?(maybe(T) & this, maybe(T) other);
 
 forall(otype T)
Index: src/libcfa/containers/maybe.c
===================================================================
--- src/libcfa/containers/maybe.c	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/libcfa/containers/maybe.c	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -19,39 +19,40 @@
 
 forall(otype T)
-void ?{}(maybe(T) * this) {
-	this->has_value = false;
+void ?{}(maybe(T) & this) {
+	this.has_value = false;
 }
 
 forall(otype T)
-void ?{}(maybe(T) * this, T value) {
-	this->has_value = true;
-	(&this->value){value};
+void ?{}(maybe(T) & this, T value) {
+	this.has_value = true;
+	(this.value){value};
 }
 
 forall(otype T)
-void ?{}(maybe(T) * this, maybe(T) other) {
-	this->has_value = other.has_value;
+void ?{}(maybe(T) & this, maybe(T) other) {
+	this.has_value = other.has_value;
 	if (other.has_value) {
-		(&this->value){other.value};
+		(this.value){other.value};
 	}
 }
 
 forall(otype T)
-maybe(T) ?=?(maybe(T) * this, maybe(T) that) {
-	if (this->has_value & that.has_value) {
-		this->value = that.value;
-	} else if (this->has_value) {
-		^(&this->value){};
-		this->has_value = false;
+maybe(T) ?=?(maybe(T) & this, maybe(T) that) {
+	if (this.has_value & that.has_value) {
+		this.value = that.value;
+	} else if (this.has_value) {
+		^(this.value){};
+		this.has_value = false;
 	} else if (that.has_value) {
-		this->has_value = true;
-		(&this->value){that.value};
+		this.has_value = true;
+		(this.value){that.value};
 	}
+	return this;
 }
 
 forall(otype T)
-void ^?{}(maybe(T) * this) {
-	if (this->has_value) {
-		^(&this->value){};
+void ^?{}(maybe(T) & this) {
+	if (this.has_value) {
+		^(this.value){};
 	}
 }
@@ -89,5 +90,5 @@
 	} else {
 		this->has_value = true;
-		(&this->value){value};
+		(this->value){value};
 	}
 }
@@ -97,5 +98,5 @@
 	if (this->has_value) {
 		this->has_value = false;
-		^(&this->value){};
+		^(this->value){};
 	}
 }
Index: src/libcfa/containers/vector
===================================================================
--- src/libcfa/containers/vector	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/libcfa/containers/vector	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -31,14 +31,14 @@
 
 forall(otype T)
-void ?{}(heap_allocator(T)* this);
+void ?{}(heap_allocator(T)& this);
 
 forall(otype T)
-void ?{}(heap_allocator(T)* this, heap_allocator(T) rhs);
+void ?{}(heap_allocator(T)& this, heap_allocator(T) rhs);
 
 forall(otype T)
-heap_allocator(T) ?=?(heap_allocator(T)* this, heap_allocator(T) rhs);
+heap_allocator(T) ?=?(heap_allocator(T)& this, heap_allocator(T) rhs);
 
 forall(otype T)
-void ^?{}(heap_allocator(T)* this);
+void ^?{}(heap_allocator(T)& this);
 
 forall(otype T)
@@ -65,14 +65,14 @@
 //Initialization
 forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
-void ?{}(vector(T, allocator_t)* this);
+void ?{}(vector(T, allocator_t)& this);
 
 forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
-void ?{}(vector(T, allocator_t)* this, vector(T, allocator_t) rhs);
+void ?{}(vector(T, allocator_t)& this, vector(T, allocator_t) rhs);
 
 forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
-vector(T, allocator_t) ?=?(vector(T, allocator_t)* this, vector(T, allocator_t) rhs);
+vector(T, allocator_t) ?=?(vector(T, allocator_t)& this, vector(T, allocator_t) rhs);
 
 forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
-void ^?{}(vector(T, allocator_t)* this);
+void ^?{}(vector(T, allocator_t)& this);
 
 forall(otype T, otype allocator_t = heap_allocator(T) | allocator_c(T, allocator_t))
Index: src/libcfa/containers/vector.c
===================================================================
--- src/libcfa/containers/vector.c	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/libcfa/containers/vector.c	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -24,15 +24,15 @@
 //Initialization
 forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
-void ?{}(vector(T, allocator_t)* this)
+void ?{}(vector(T, allocator_t)& this)
 {
-	(&this->storage){};
-	this->size = 0;
+	(this.storage){};
+	this.size = 0;
 }
 
 forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
-void ?{}(vector(T, allocator_t)* this, vector(T, allocator_t) rhs)
+void ?{}(vector(T, allocator_t)& this, vector(T, allocator_t) rhs)
 {
-	(&this->storage){ rhs.storage };
-	copy_internal(this, &rhs);
+	(this.storage){ rhs.storage };
+	copy_internal(&this, &rhs);
 }
 
@@ -46,8 +46,8 @@
 
 forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
-void ^?{}(vector(T, allocator_t)* this)
+void ^?{}(vector(T, allocator_t)& this)
 {
-	clear(this);
-	^(&this->storage){};
+	clear(&this);
+	^(this.storage){};
 }
 
@@ -66,5 +66,5 @@
 {
 	this->size--;
-	^(&data(&this->storage)[this->size]){};
+	^(data(&this->storage)[this->size]){};
 }
 
@@ -74,5 +74,5 @@
 	for(size_t i = 0; i < this->size; i++)
 	{
-		^(&data(&this->storage)[this->size]){};
+		^(data(&this->storage)[this->size]){};
 	}
 	this->size = 0;
@@ -87,5 +87,5 @@
 	this->size = other->size;
 	for(size_t i = 0; i < this->size; i++) {
-		(&data(&this->storage)[this->size]){ data(&other->storage)[other->size] };
+		(data(&this->storage)[this->size]){ data(&other->storage)[other->size] };
 	}
 }
@@ -94,29 +94,29 @@
 //Allocator
 forall(otype T)
-void ?{}(heap_allocator(T)* this)
+void ?{}(heap_allocator(T)& this)
 {
-	this->storage = 0;
-	this->capacity = 0;
+	this.storage = 0;
+	this.capacity = 0;
 }
 
 forall(otype T)
-void ?{}(heap_allocator(T)* this, heap_allocator(T) rhs)
+void ?{}(heap_allocator(T)& this, heap_allocator(T) rhs)
 {
-	this->capacity = rhs.capacity;
-	this->storage = (T*)realloc((void*)this->storage, this->capacity * sizeof(T));
+	this.capacity = rhs.capacity;
+	this.storage = (T*)realloc((void*)this.storage, this.capacity * sizeof(T));
 }
 
 forall(otype T)
-heap_allocator(T) ?=?(heap_allocator(T)* this, heap_allocator(T) rhs)
+heap_allocator(T) ?=?(heap_allocator(T)& this, heap_allocator(T) rhs)
 {
-	this->capacity = rhs.capacity;
-	this->storage = (T*)realloc((void*)this->storage, this->capacity * sizeof(T));
-	return *this;
+	this.capacity = rhs.capacity;
+	this.storage = (T*)realloc((void*)this.storage, this.capacity * sizeof(T));
+	return this;
 }
 
 forall(otype T)
-void ^?{}(heap_allocator(T)* this)
+void ^?{}(heap_allocator(T)& this)
 {
-	free(this->storage);
+	free(this.storage);
 }
 
Index: src/libcfa/interpose.c
===================================================================
--- src/libcfa/interpose.c	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/libcfa/interpose.c	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -10,6 +10,6 @@
 // Author           : Thierry Delisle
 // Created On       : Wed Mar 29 16:10:31 2017
-// Last Modified By : 
-// Last Modified On : 
+// Last Modified By :
+// Last Modified On :
 // Update Count     : 0
 //
@@ -50,5 +50,5 @@
 
 	union { generic_fptr_t fptr; void* ptr; } originalFunc;
-	
+
 	#if defined( _GNU_SOURCE )
 		if ( version ) {
@@ -60,7 +60,7 @@
 		originalFunc.ptr = dlsym( library, symbol );
 	#endif // _GNU_SOURCE
-	
+
 	error = dlerror();
-	if ( error ) abortf( "interpose_symbol : internal error, %s\n", error ); 
+	if ( error ) abortf( "interpose_symbol : internal error, %s\n", error );
 
 	return originalFunc.fptr;
@@ -75,7 +75,7 @@
 forall(dtype T)
 static inline void assign_ptr( T** symbol_ptr, const char * symbol_name, const char * version) {
-	union { 
+	union {
 		generic_fptr_t gp;
-		T* tp; 
+		T* tp;
 	} u;
 
Index: src/libcfa/stdlib
===================================================================
--- src/libcfa/stdlib	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/libcfa/stdlib	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -134,12 +134,12 @@
 
 // allocation/deallocation and constructor/destructor, non-array types
-forall( dtype T | sized(T), ttype Params | { void ?{}( T *, Params ); } ) T * new( Params p );
-forall( dtype T | { void ^?{}( T * ); } ) void delete( T * ptr );
-forall( dtype T, ttype Params | { void ^?{}( T * ); void delete( Params ); } ) void delete( T * ptr, Params rest );
+forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );
+forall( dtype T | { void ^?{}( T & ); } ) void delete( T * ptr );
+forall( dtype T, ttype Params | { void ^?{}( T & ); void delete( Params ); } ) void delete( T * ptr, Params rest );
 
 // allocation/deallocation and constructor/destructor, array types
-forall( dtype T | sized(T), ttype Params | { void ?{}( T *, Params ); } ) T * anew( size_t dim, Params p );
-forall( dtype T | sized(T) | { void ^?{}( T * ); } ) void adelete( size_t dim, T arr[] );
-forall( dtype T | sized(T) | { void ^?{}( T * ); }, ttype Params | { void adelete( Params ); } ) void adelete( size_t dim, T arr[], Params rest );
+forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p );
+forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] );
+forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } ) void adelete( size_t dim, T arr[], Params rest );
 
 //---------------------------------------
@@ -200,5 +200,5 @@
 double abs( double _Complex );
 long double abs( long double _Complex );
-forall( otype T | { void ?{}( T *, zero_t ); int ?<?( T, T ); T -?( T ); } )
+forall( otype T | { void ?{}( T &, zero_t ); int ?<?( T, T ); T -?( T ); } )
 T abs( T );
 
Index: src/libcfa/stdlib.c
===================================================================
--- src/libcfa/stdlib.c	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/libcfa/stdlib.c	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -34,15 +34,15 @@
 	if ( nlen > olen ) {								// larger ?
 		memset( nptr + olen, (int)fill, nlen - olen );	// initialize added storage
-	} // 
+	} //
     return (T *)nptr;
 } // alloc
 
 // allocation/deallocation and constructor/destructor, non-array types
-forall( dtype T | sized(T), ttype Params | { void ?{}( T *, Params ); } )
+forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } )
 T * new( Params p ) {
 	return (malloc()){ p };								// run constructor
 } // new
 
-forall( dtype T | { void ^?{}( T * ); } )
+forall( dtype T | { void ^?{}( T & ); } )
 void delete( T * ptr ) {
 	if ( ptr ) {										// ignore null
@@ -52,5 +52,5 @@
 } // delete
 
-forall( dtype T, ttype Params | { void ^?{}( T * ); void delete( Params ); } )
+forall( dtype T, ttype Params | { void ^?{}( T & ); void delete( Params ); } )
 void delete( T * ptr, Params rest ) {
 	if ( ptr ) {										// ignore null
@@ -63,5 +63,5 @@
 
 // allocation/deallocation and constructor/destructor, array types
-forall( dtype T | sized(T), ttype Params | { void ?{}( T *, Params ); } )
+forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } )
 T * anew( size_t dim, Params p ) {
 	T *arr = alloc( dim );
@@ -72,5 +72,5 @@
 } // anew
 
-forall( dtype T | sized(T) | { void ^?{}( T * ); } )
+forall( dtype T | sized(T) | { void ^?{}( T & ); } )
 void adelete( size_t dim, T arr[] ) {
 	if ( arr ) {										// ignore null
@@ -82,5 +82,5 @@
 } // adelete
 
-forall( dtype T | sized(T) | { void ^?{}( T * ); }, ttype Params | { void adelete( Params ); } )
+forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } )
 void adelete( size_t dim, T arr[], Params rest ) {
 	if ( arr ) {										// ignore null
Index: src/prelude/prelude.cf
===================================================================
--- src/prelude/prelude.cf	(revision 3d4b23fa9ef416e3543e652102009137f340d4e5)
+++ src/prelude/prelude.cf	(revision 9a1e509e6ded571c2f6355253b2c7bfa0b4a2340)
@@ -30,49 +30,49 @@
 // ------------------------------------------------------------
 
-_Bool			?++( _Bool * ),				?++( volatile _Bool * );
-_Bool			?--( _Bool * ),				?--( volatile _Bool * );
-unsigned char		?++( unsigned char * ),			?++( volatile unsigned char * );
-signed int		?++( signed int * ),			?++( volatile signed int * );
-signed int		?--( signed int * ),			?--( volatile signed int * );
-unsigned int		?++( unsigned int * ),			?++( volatile unsigned int * );
-unsigned int		?--( unsigned int * ),			?--( volatile unsigned int * );
-signed long int		?++( signed long int * ),		?++( volatile signed long int * );
-signed long int		?--( signed long int * ),		?--( volatile signed long int * );
-unsigned long int	?++( unsigned long int * ),		?++( volatile unsigned long int * );
-unsigned long int	?--( unsigned long int * ),		?--( volatile unsigned long int * );
-signed long long int	?++( signed long long int * ),		?++( volatile signed long long int * );
-signed long long int	?--( signed long long int * ),		?--( volatile signed long long int * );
-unsigned long long int	?++( unsigned long long int * ),	?++( volatile unsigned long long int * );
-unsigned long long int	?--( unsigned long long int * ),	?--( volatile unsigned long long int * );
-float			?++( float * ),				?++( volatile float * );
-float			?--( float * ),				?--( volatile float * );
-double			?++( double * ),			?++( volatile double * );
-double			?--( double * ),			?--( volatile double * );
-long double		?++( long double * ),			?++( volatile long double * );
-long double		?--( long double * ),			?--( volatile long double * );
-float _Complex		?++( float _Complex * ),		?++( volatile float _Complex * );
-float _Complex		?--( float _Complex * ),		?--( volatile float _Complex * );
-double _Complex		?++( double _Complex * ),		?++( volatile double _Complex * );
-double _Complex		?--( double _Complex * ),		?--( volatile double _Complex * );
-long double _Complex	?++( long double _Complex * ),		?++( volatile long double _Complex * );
-long double _Complex	?--( long double _Complex * ),		?--( volatile long double _Complex * );
-
-forall( dtype T | sized(T) ) T *			 ?++(		     T ** );
-forall( dtype T | sized(T) ) const T *		 ?++( const	     T ** );
-forall( dtype T | sized(T) ) volatile T *		 ?++(	    volatile T ** );
-forall( dtype T | sized(T) ) const volatile T *	 ?++( const volatile T ** );
-forall( dtype T | sized(T) ) T *			 ?--(		     T ** );
-forall( dtype T | sized(T) ) const T *		 ?--( const	     T ** );
-forall( dtype T | sized(T) ) volatile T *		 ?--(	    volatile T ** );
-forall( dtype T | sized(T) ) const volatile T *	 ?--( const volatile T ** );
-
-forall( dtype T | sized(T) ) lvalue T		 ?[?](		      T *,	    ptrdiff_t );
-forall( dtype T | sized(T) ) const lvalue T	 ?[?]( const	      T *,	    ptrdiff_t );
-forall( dtype T | sized(T) ) volatile lvalue T	 ?[?](       volatile T *,	    ptrdiff_t );
-forall( dtype T | sized(T) ) const volatile lvalue T ?[?]( const volatile T *,	    ptrdiff_t );
-forall( dtype T | sized(T) ) lvalue T		 ?[?](		ptrdiff_t,		  T * );
-forall( dtype T | sized(T) ) const lvalue T	 ?[?](		ptrdiff_t, const	  T * );
-forall( dtype T | sized(T) ) volatile lvalue T	 ?[?](		ptrdiff_t,	 volatile T * );
-forall( dtype T | sized(T) ) const volatile lvalue T ?[?](		ptrdiff_t, const volatile T * );
+_Bool			?++( _Bool & ),				?++( volatile _Bool & );
+_Bool			?--( _Bool & ),				?--( volatile _Bool & );
+unsigned char		?++( unsigned char & ),			?++( volatile unsigned char & );
+signed int		?++( signed int & ),			?++( volatile signed int & );
+signed int		?--( signed int & ),			?--( volatile signed int & );
+unsigned int		?++( unsigned int & ),			?++( volatile unsigned int & );
+unsigned int		?--( unsigned int & ),			?--( volatile unsigned int & );
+signed long int		?++( signed long int & ),		?++( volatile signed long int & );
+signed long int		?--( signed long int & ),		?--( volatile signed long int & );
+unsigned long int	?++( unsigned long int & ),		?++( volatile unsigned long int & );
+unsigned long int	?--( unsigned long int & ),		?--( volatile unsigned long int & );
+signed long long int	?++( signed long long int & ),		?++( volatile signed long long int & );
+signed long long int	?--( signed long long int & ),		?--( volatile signed long long int & );
+unsigned long long int	?++( unsigned long long int & ),	?++( volatile unsigned long long int & );
+unsigned long long int	?--( unsigned long long int & ),	?--( volatile unsigned long long int & );
+float			?++( float & ),				?++( volatile float & );
+float			?--( float & ),				?--( volatile float & );
+double			?++( double & ),			?++( volatile double & );
+double			?--( double & ),			?--( volatile double & );
+long double		?++( long double & ),			?++( volatile long double & );
+long double		?--( long double & ),			?--( volatile long double & );
+float _Complex		?++( float _Complex & ),		?++( volatile float _Complex & );
+float _Complex		?--( float _Complex & ),		?--( volatile float _Complex & );
+double _Complex		?++( double _Complex & ),		?++( volatile double _Complex & );
+double _Complex		?--( double _Complex & ),		?--( volatile double _Complex & );
+long double _Complex	?++( long double _Complex & ),		?++( volatile long double _Complex & );
+long double _Complex	?--( long double _Complex & ),		?--( volatile long double _Complex & );
+
+forall( dtype T | sized(T) ) T *			 ?++(		     T *& );
+forall( dtype T | sized(T) ) const T *		 ?++( const	     T *& );
+forall( dtype T | sized(T) ) volatile T *		 ?++(	    volatile T *& );
+forall( dtype T | sized(T) ) const volatile T *	 ?++( const volatile T *& );
+forall( dtype T | sized(T) ) T *			 ?--(		     T *& );
+forall( dtype T | sized(T) ) const T *		 ?--( const	     T *& );
+forall( dtype T | sized(T) ) volatile T *		 ?--(	    volatile T *& );
+forall( dtype T | sized(T) ) const volatile T *	 ?--( const volatile T *& );
+
+forall( dtype T | sized(T) ) T &		 ?[?](		      T *,	    ptrdiff_t );
+forall( dtype T | sized(T) ) const T &	 ?[?]( const	      T *,	    ptrdiff_t );
+forall( dtype T | sized(T) ) volatile T &	 ?[?](       volatile T *,	    ptrdiff_t );
+forall( dtype T | sized(T) ) const volatile T & ?[?]( const volatile T *,	    ptrdiff_t );
+forall( dtype T | sized(T) ) T &		 ?[?](		ptrdiff_t,		  T * );
+forall( dtype T | sized(T) ) const T &	 ?[?](		ptrdiff_t, const	  T * );
+forall( dtype T | sized(T) ) volatile T &	 ?[?](		ptrdiff_t,	 volatile T * );
+forall( dtype T | sized(T) ) const volatile T & ?[?](		ptrdiff_t, const volatile T * );
 
 // ------------------------------------------------------------
@@ -82,32 +82,32 @@
 // ------------------------------------------------------------
 
-_Bool			++?( _Bool * ),				--?( _Bool * );
-signed int		++?( signed int * ),			--?( signed int * );
-unsigned int		++?( unsigned int * ),			--?( unsigned int * );
-signed long int		++?( signed long int * ),		--?( signed long int * );
-unsigned long int	++?( unsigned long int * ),		--?( unsigned long int * );
-signed long long int	++?( signed long long int * ),		--?( signed long long int * );
-unsigned long long int	++?( unsigned long long int * ),	--?( unsigned long long int * );
-float			++?( float * ),				--?( float * );
-double			++?( double * ),			--?( double * );
-long double		++?( long double * ),			--?( long double * );
-float _Complex		++?( float _Complex * ),		--?( float _Complex * );
-double _Complex		++?( double _Complex * ),		--?( double _Complex * );
-long double _Complex	++?( long double _Complex * ),		--?( long double _Complex * );
-
-forall( dtype T | sized(T) ) T *			 ++?(		     T ** );
-forall( dtype T | sized(T) ) const T *		 ++?( const	     T ** );
-forall( dtype T | sized(T) ) volatile T *		 ++?(	    volatile T ** );
-forall( dtype T | sized(T) ) const volatile T *	 ++?( const volatile T ** );
-forall( dtype T | sized(T) ) T *			 --?(		     T ** );
-forall( dtype T | sized(T) ) const T *		 --?( const	     T ** );
-forall( dtype T | sized(T) ) volatile T *		 --?(	    volatile T ** );
-forall( dtype T | sized(T) ) const volatile T *	 --?( const volatile T ** );
-
-forall( dtype T | sized(T) ) lvalue T		 *?(		     T * );
-forall( dtype T | sized(T) ) const lvalue T		 *?( const	     T * );
-forall( dtype T | sized(T) ) volatile lvalue T	 *?(       volatile  T * );
-forall( dtype T | sized(T) ) const volatile lvalue T *?( const volatile  T * );
-forall( ftype FT ) lvalue FT		 *?( FT * );
+_Bool			++?( _Bool & ),				--?( _Bool & );
+signed int		++?( signed int & ),			--?( signed int & );
+unsigned int		++?( unsigned int & ),			--?( unsigned int & );
+signed long int		++?( signed long int & ),		--?( signed long int & );
+unsigned long int	++?( unsigned long int & ),		--?( unsigned long int & );
+signed long long int	++?( signed long long int & ),		--?( signed long long int & );
+unsigned long long int	++?( unsigned long long int & ),	--?( unsigned long long int & );
+float			++?( float & ),				--?( float & );
+double			++?( double & ),			--?( double & );
+long double		++?( long double & ),			--?( long double & );
+float _Complex		++?( float _Complex & ),		--?( float _Complex & );
+double _Complex		++?( double _Complex & ),		--?( double _Complex & );
+long double _Complex	++?( long double _Complex & ),		--?( long double _Complex & );
+
+forall( dtype T | sized(T) ) T *			 ++?(		     T *& );
+forall( dtype T | sized(T) ) const T *		 ++?( const	     T *& );
+forall( dtype T | sized(T) ) volatile T *		 ++?(	    volatile T *& );
+forall( dtype T | sized(T) ) const volatile T *	 ++?( const volatile T *& );
+forall( dtype T | sized(T) ) T *			 --?(		     T *& );
+forall( dtype T | sized(T) ) const T *		 --?( const	     T *& );
+forall( dtype T | sized(T) ) volatile T *		 --?(	    volatile T *& );
+forall( dtype T | sized(T) ) const volatile T *	 --?( const volatile T *& );
+
+forall( dtype T | sized(T) ) T &		 *?(		     T * );
+forall( dtype T | sized(T) ) const T &		 *?( const	     T * );
+forall( dtype T | sized(T) ) volatile T &	 *?(       volatile  T * );
+forall( dtype T | sized(T) ) const volatile T & *?( const volatile  T * );
+forall( ftype FT ) FT &		 *?( FT * );
 
 _Bool			+?( _Bool ),			-?( _Bool ),			~?( _Bool );
@@ -366,295 +366,295 @@
 // ------------------------------------------------------------
 
-forall( ftype FT ) FT *			?=?( FT **, FT * );
-forall( ftype FT ) FT *			?=?( FT * volatile *, FT * );
-
-forall( dtype DT ) DT *			?=?(		     DT *	   *,			DT * );
-forall( dtype DT ) DT *			?=?(		     DT * volatile *,			DT * );
-forall( dtype DT ) const DT *		?=?( const	     DT *	   *,			DT * );
-forall( dtype DT ) const DT *		?=?( const	     DT * volatile *,			DT * );
-forall( dtype DT ) const DT *		?=?( const	     DT *	   *, const		DT * );
-forall( dtype DT ) const DT *		?=?( const	     DT * volatile *, const		DT * );
-forall( dtype DT ) volatile DT *	?=?(	   volatile  DT *	   *,			DT * );
-forall( dtype DT ) volatile DT *	?=?(	   volatile  DT * volatile *,			DT * );
-forall( dtype DT ) volatile DT *	?=?(	   volatile  DT *	   *,	    volatile	DT * );
-forall( dtype DT ) volatile DT *	?=?(	   volatile  DT * volatile *,	    volatile	DT * );
-
-forall( dtype DT ) const volatile DT *	?=?( const volatile  DT *	   *,			DT * );
-forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT * volatile *,			DT * );
-forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT *	   *, const		DT * );
-forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT * volatile *, const		DT * );
-forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT *	   *,	    volatile	DT * );
-forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT * volatile *,	    volatile	DT * );
-forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT *	   *, const volatile	DT * );
-forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT * volatile *, const volatile	DT * );
-
-forall( dtype DT ) DT *			?=?(		     DT *	   *,			void * );
-forall( dtype DT ) DT *			?=?(		     DT * volatile *,			void * );
-forall( dtype DT ) const DT *		?=?( const	     DT *	   *,			void * );
-forall( dtype DT ) const DT *		?=?( const	     DT * volatile *,			void * );
-forall( dtype DT ) const DT *		?=?( const	     DT *	   *, const		void * );
-forall( dtype DT ) const DT *		?=?( const	     DT * volatile *, const		void * );
-forall( dtype DT ) volatile DT *	?=?(	   volatile  DT *	   *,			void * );
-forall( dtype DT ) volatile DT *	?=?(	   volatile  DT * volatile *,			void * );
-forall( dtype DT ) volatile DT *	?=?(	   volatile  DT *	   *,	    volatile	void * );
-forall( dtype DT ) volatile DT *	?=?(	   volatile  DT * volatile *,	    volatile	void * );
-
-forall( dtype DT ) const volatile DT *	?=?( const volatile  DT *	   *,			void * );
-forall( dtype DT ) const volatile DT *	?=?( const volatile  DT * volatile *,			void * );
-forall( dtype DT ) const volatile DT *	?=?( const volatile  DT *	   *, const		void * );
-forall( dtype DT ) const volatile DT *	?=?( const volatile  DT * volatile *, const		void * );
-forall( dtype DT ) const volatile DT *	?=?( const volatile  DT *	   *,	    volatile	void * );
-forall( dtype DT ) const volatile DT *	?=?( const volatile  DT * volatile *,	    volatile	void * );
-forall( dtype DT ) const volatile DT *	?=?( const volatile  DT *	   *, const volatile	void * );
-forall( dtype DT ) const volatile DT *	?=?( const volatile  DT * volatile *, const volatile	void * );
-
-forall( dtype DT ) void *		 ?=?(		     void *	     *,			DT * );
-forall( dtype DT ) void *		 ?=?(		     void * volatile *,			DT * );
-forall( dtype DT ) const void *		 ?=?( const	     void *	     *,			DT * );
-forall( dtype DT ) const void *		 ?=?( const	     void * volatile *,			DT * );
-forall( dtype DT ) const void *		 ?=?( const	     void *	     *, const		DT * );
-forall( dtype DT ) const void *		 ?=?( const	     void * volatile *, const		DT * );
-forall( dtype DT ) volatile void *	 ?=?(	    volatile void *	     *,			DT * );
-forall( dtype DT ) volatile void *	 ?=?(	    volatile void * volatile *,			DT * );
-forall( dtype DT ) volatile void *	 ?=?(	    volatile void *	     *,	      volatile	DT * );
-forall( dtype DT ) volatile void *	 ?=?(	    volatile void * volatile *,	      volatile	DT * );
-forall( dtype DT ) const volatile void * ?=?( const volatile void *	     *,			DT * );
-forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile *,			DT * );
-forall( dtype DT ) const volatile void * ?=?( const volatile void *	     *, const		DT * );
-forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile *, const		DT * );
-forall( dtype DT ) const volatile void * ?=?( const volatile void *	     *,	      volatile	DT * );
-forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile *,	      volatile	DT * );
-forall( dtype DT ) const volatile void * ?=?( const volatile void *	     *, const volatile	DT * );
-forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile *, const volatile	DT * );
-
-void *			?=?(		    void *	    *,		      void * );
-void *			?=?(		    void * volatile *,		      void * );
-const void *		?=?( const	    void *	    *,		      void * );
-const void *		?=?( const	    void * volatile *,		      void * );
-const void *		?=?( const	    void *	    *, const	      void * );
-const void *		?=?( const	    void * volatile *, const	      void * );
-volatile void *		?=?(	   volatile void *	    *,		      void * );
-volatile void *		?=?(	   volatile void * volatile *,		      void * );
-volatile void *		?=?(	   volatile void *	    *,	     volatile void * );
-volatile void *		?=?(	   volatile void * volatile *,	     volatile void * );
-const volatile void *	?=?( const volatile void *	    *,		      void * );
-const volatile void *	?=?( const volatile void * volatile *,		      void * );
-const volatile void *	?=?( const volatile void *	    *, const	      void * );
-const volatile void *	?=?( const volatile void * volatile *, const	      void * );
-const volatile void *	?=?( const volatile void *	    *,	     volatile void * );
-const volatile void *	?=?( const volatile void * volatile *,	     volatile void * );
-const volatile void *	?=?( const volatile void *	    *, const volatile void * );
-const volatile void *	?=?( const volatile void * volatile *, const volatile void * );
-
-// //forall( dtype DT ) DT *			?=?(		    DT *	  *, zero_t );
-// //forall( dtype DT ) DT *			?=?(		    DT * volatile *, zero_t );
-// forall( dtype DT ) const DT *		?=?( const	    DT *	  *, zero_t );
-// forall( dtype DT ) const DT *		?=?( const	    DT * volatile *, zero_t );
-// //forall( dtype DT ) volatile DT *	?=?( volatile	    DT *	  *, zero_t );
-// //forall( dtype DT ) volatile DT *	?=?( volatile	    DT * volatile *,  );
-// forall( dtype DT ) const volatile DT *	?=?( const volatile DT *	  *, zero_t );
-// forall( dtype DT ) const volatile DT *	?=?( const volatile DT * volatile *, zero_t );
-
-// forall( ftype FT ) FT *			?=?( FT *	   *, zero_t );
-// forall( ftype FT ) FT *			?=?( FT * volatile *, zero_t );
-
-forall( dtype T | sized(T) ) T *			?+=?(		     T *	  *, ptrdiff_t );
-forall( dtype T | sized(T) ) T *			?+=?(		     T * volatile *, ptrdiff_t );
-forall( dtype T | sized(T) ) const T *		?+=?( const	     T *	  *, ptrdiff_t );
-forall( dtype T | sized(T) ) const T *		?+=?( const	     T * volatile *, ptrdiff_t );
-forall( dtype T | sized(T) ) volatile T *		?+=?(	    volatile T *	  *, ptrdiff_t );
-forall( dtype T | sized(T) ) volatile T *		?+=?(	    volatile T * volatile *, ptrdiff_t );
-forall( dtype T | sized(T) ) const volatile T *	?+=?( const volatile T *	  *, ptrdiff_t );
-forall( dtype T | sized(T) ) const volatile T *	?+=?( const volatile T * volatile *, ptrdiff_t );
-forall( dtype T | sized(T) ) T *			?-=?(		     T *	  *, ptrdiff_t );
-forall( dtype T | sized(T) ) T *			?-=?(		     T * volatile *, ptrdiff_t );
-forall( dtype T | sized(T) ) const T *		?-=?( const	     T *	  *, ptrdiff_t );
-forall( dtype T | sized(T) ) const T *		?-=?( const	     T * volatile *, ptrdiff_t );
-forall( dtype T | sized(T) ) volatile T *		?-=?(	    volatile T *	  *, ptrdiff_t );
-forall( dtype T | sized(T) ) volatile T *		?-=?(	    volatile T * volatile *, ptrdiff_t );
-forall( dtype T | sized(T) ) const volatile T *	?-=?( const volatile T *	  *, ptrdiff_t );
-forall( dtype T | sized(T) ) const volatile T *	?-=?( const volatile T * volatile *, ptrdiff_t );
-
-_Bool			?=?( _Bool *, _Bool ),					?=?( volatile _Bool *, _Bool );
-char			?=?( char *, char ),					?=?( volatile char *, char );
-char signed		?=?( char signed *, char signed ),			?=?( volatile char signed *, char signed );
-char unsigned		?=?( char unsigned *, char unsigned ),			?=?( volatile char unsigned *, char unsigned );
-int short		?=?( int short *, int short ),				?=?( volatile int short *, int short );
-int short unsigned	?=?( int short unsigned *, int short unsigned ),	?=?( volatile int short unsigned *, int short unsigned );
-signed int		?=?( signed int *, signed int ),			?=?( volatile signed int *, signed int );
-unsigned int		?=?( unsigned *, unsigned ),				?=?( volatile unsigned *, unsigned );
-signed long int		?=?( signed long int *, signed long int ),		?=?( volatile signed long int *, signed long int );
-unsigned long int	?=?( unsigned long int *, unsigned long int ),		?=?( volatile unsigned long int *, unsigned long int );
-signed long long int	?=?( signed long long int *, signed long long int ),	?=?( volatile signed long long int *, signed long long int );
-unsigned long long int	?=?( unsigned long long int *, unsigned long long int ), ?=?( volatile unsigned long long int *, unsigned long long int );
-zero_t		?=?( zero_t *, zero_t );
-one_t			?=?( one_t *, one_t );
-
-
-_Bool			?*=?( _Bool *, _Bool ),					?*=?( volatile _Bool *, _Bool );
-char			?*=?( char *, char ),					?*=?( volatile char *, char );
-char signed		?*=?( char signed *, char signed ),			?*=?( volatile char signed *, char signed );
-char unsigned		?*=?( char unsigned *, char unsigned ),			?*=?( volatile char unsigned *, char unsigned );
-int short		?*=?( int short *, int short ),				?*=?( volatile int short *, int short );
-int short unsigned	?*=?( int short unsigned *, int short unsigned ),	?*=?( volatile int short unsigned *, int short unsigned );
-signed int		?*=?( signed int *, signed int ),			?*=?( volatile signed int *, signed int );
-unsigned int		?*=?( unsigned *, unsigned ),				?*=?( volatile unsigned *, unsigned );
-signed long int		?*=?( signed long int *, signed long int ),		?*=?( volatile signed long int *, signed long int );
-unsigned long int	?*=?( unsigned long int *, unsigned long int ),		?*=?( volatile unsigned long int *, unsigned long int );
-signed long long int	?*=?( signed long long int *, signed long long int ),	?*=?( volatile signed long long int *, signed long long int );
-unsigned long long int	?*=?( unsigned long long int *, unsigned long long int ), ?*=?( volatile unsigned long long int *, unsigned long long int );
-
-_Bool			?/=?( _Bool *, _Bool ),					?/=?( volatile _Bool *, _Bool );
-char			?/=?( char *, char ),					?/=?( volatile char *, char );
-char signed		?/=?( char signed *, char signed ),			?/=?( volatile char signed *, char signed );
-char unsigned		?/=?( char unsigned *, char unsigned ),			?/=?( volatile char unsigned *, char unsigned );
-int short		?/=?( int short *, int short ),				?/=?( volatile int short *, int short );
-int short unsigned	?/=?( int short unsigned *, int short unsigned ),	?/=?( volatile int short unsigned *, int short unsigned );
-signed int		?/=?( signed int *, signed int ),			?/=?( volatile signed int *, signed int );
-unsigned int		?/=?( unsigned *, unsigned ),				?/=?( volatile unsigned *, unsigned );
-signed long int		?/=?( signed long int *, signed long int ),		?/=?( volatile signed long int *, signed long int );
-unsigned long int	?/=?( unsigned long int *, unsigned long int ),		?/=?( volatile unsigned long int *, unsigned long int );
-signed long long int	?/=?( signed long long int *, signed long long int ),	?/=?( volatile signed long long int *, signed long long int );
-unsigned long long int	?/=?( unsigned long long int *, unsigned long long int ), ?/=?( volatile unsigned long long int *, unsigned long long int );
-
-_Bool			?%=?( _Bool *, _Bool ),					?%=?( volatile _Bool *, _Bool );
-char			?%=?( char *, char ),					?%=?( volatile char *, char );
-char signed		?%=?( char signed *, char signed ),			?%=?( volatile char signed *, char signed );
-char unsigned		?%=?( char unsigned *, char unsigned ),			?%=?( volatile char unsigned *, char unsigned );
-int short		?%=?( int short *, int short ),				?%=?( volatile int short *, int short );
-int short unsigned	?%=?( int short unsigned *, int short unsigned ),	?%=?( volatile int short unsigned *, int short unsigned );
-signed int		?%=?( signed int *, signed int ),			?%=?( volatile signed int *, signed int );
-unsigned int		?%=?( unsigned *, unsigned ),				?%=?( volatile unsigned *, unsigned );
-signed long int		?%=?( signed long int *, signed long int ),		?%=?( volatile signed long int *, signed long int );
-unsigned long int	?%=?( unsigned long int *, unsigned long int ),		?%=?( volatile unsigned long int *, unsigned long int );
-signed long long int	?%=?( signed long long int *, signed long long int ),	?%=?( volatile signed long long int *, signed long long int );
-unsigned long long int	?%=?( unsigned long long int *, unsigned long long int ), ?%=?( volatile unsigned long long int *, unsigned long long int );
-
-_Bool			?+=?( _Bool *, _Bool ),					?+=?( volatile _Bool *, _Bool );
-char			?+=?( char *, char ),					?+=?( volatile char *, char );
-char signed		?+=?( char signed *, char signed ),			?+=?( volatile char signed *, char signed );
-char unsigned		?+=?( char unsigned *, char unsigned ),			?+=?( volatile char unsigned *, char unsigned );
-int short		?+=?( int short *, int short ),				?+=?( volatile int short *, int short );
-int short unsigned	?+=?( int short unsigned *, int short unsigned ),	?+=?( volatile int short unsigned *, int short unsigned );
-signed int		?+=?( signed int *, signed int ),			?+=?( volatile signed int *, signed int );
-unsigned int		?+=?( unsigned *, unsigned ),				?+=?( volatile unsigned *, unsigned );
-signed long int		?+=?( signed long int *, signed long int ),		?+=?( volatile signed long int *, signed long int );
-unsigned long int	?+=?( unsigned long int *, unsigned long int ),		?+=?( volatile unsigned long int *, unsigned long int );
-signed long long int	?+=?( signed long long int *, signed long long int ),	?+=?( volatile signed long long int *, signed long long int );
-unsigned long long int	?+=?( unsigned long long int *, unsigned long long int ), ?+=?( volatile unsigned long long int *, unsigned long long int );
-
-_Bool			?-=?( _Bool *, _Bool ),					?-=?( volatile _Bool *, _Bool );
-char			?-=?( char *, char ),					?-=?( volatile char *, char );
-char signed		?-=?( char signed *, char signed ),			?-=?( volatile char signed *, char signed );
-char unsigned		?-=?( char unsigned *, char unsigned ),			?-=?( volatile char unsigned *, char unsigned );
-int short		?-=?( int short *, int short ),				?-=?( volatile int short *, int short );
-int short unsigned	?-=?( int short unsigned *, int short unsigned ),	?-=?( volatile int short unsigned *, int short unsigned );
-signed int		?-=?( signed int *, signed int ),			?-=?( volatile signed int *, signed int );
-unsigned int		?-=?( unsigned *, unsigned ),				?-=?( volatile unsigned *, unsigned );
-signed long int		?-=?( signed long int *, signed long int ),		?-=?( volatile signed long int *, signed long int );
-unsigned long int	?-=?( unsigned long int *, unsigned long int ),		?-=?( volatile unsigned long int *, unsigned long int );
-signed long long int	?-=?( signed long long int *, signed long long int ),	?-=?( volatile signed long long int *, signed long long int );
-unsigned long long int	?-=?( unsigned long long int *, unsigned long long int ), ?-=?( volatile unsigned long long int *, unsigned long long int );
-
-_Bool			?<<=?( _Bool *, _Bool ),				?<<=?( volatile _Bool *, _Bool );
-char			?<<=?( char *, char ),					?<<=?( volatile char *, char );
-char signed		?<<=?( char signed *, char signed ),			?<<=?( volatile char signed *, char signed );
-char unsigned		?<<=?( char unsigned *, char unsigned ),		?<<=?( volatile char unsigned *, char unsigned );
-int short		?<<=?( int short *, int short ),			?<<=?( volatile int short *, int short );
-int short unsigned	?<<=?( int short unsigned *, int short unsigned ),	?<<=?( volatile int short unsigned *, int short unsigned );
-signed int		?<<=?( signed int *, signed int ),			?<<=?( volatile signed int *, signed int );
-unsigned int		?<<=?( unsigned *, unsigned ),				?<<=?( volatile unsigned *, unsigned );
-signed long int		?<<=?( signed long int *, signed long int ),		?<<=?( volatile signed long int *, signed long int );
-unsigned long int	?<<=?( unsigned long int *, unsigned long int ),	?<<=?( volatile unsigned long int *, unsigned long int );
-signed long long int	?<<=?( signed long long int *, signed long long int ),	?<<=?( volatile signed long long int *, signed long long int );
-unsigned long long int	?<<=?( unsigned long long int *, unsigned long long int ), ?<<=?( volatile unsigned long long int *, unsigned long long int );
-
-_Bool			?>>=?( _Bool *, _Bool ),				?>>=?( volatile _Bool *, _Bool );
-char			?>>=?( char *, char ),					?>>=?( volatile char *, char );
-char signed		?>>=?( char signed *, char signed ),			?>>=?( volatile char signed *, char signed );
-char unsigned		?>>=?( char unsigned *, char unsigned ),		?>>=?( volatile char unsigned *, char unsigned );
-int short		?>>=?( int short *, int short ),			?>>=?( volatile int short *, int short );
-int short unsigned	?>>=?( int short unsigned *, int short unsigned ),	?>>=?( volatile int short unsigned *, int short unsigned );
-signed int		?>>=?( signed int *, signed int ),			?>>=?( volatile signed int *, signed int );
-unsigned int		?>>=?( unsigned *, unsigned ),				?>>=?( volatile unsigned *, unsigned );
-signed long int		?>>=?( signed long int *, signed long int ),		?>>=?( volatile signed long int *, signed long int );
-unsigned long int	?>>=?( unsigned long int *, unsigned long int ),	?>>=?( volatile unsigned long int *, unsigned long int );
-signed long long int	?>>=?( signed long long int *, signed long long int ),	?>>=?( volatile signed long long int *, signed long long int );
-unsigned long long int	?>>=?( unsigned long long int *, unsigned long long int ), ?>>=?( volatile unsigned long long int *, unsigned long long int );
-
-_Bool			?&=?( _Bool *, _Bool ),					?&=?( volatile _Bool *, _Bool );
-char			?&=?( char *, char ),					?&=?( volatile char *, char );
-char signed		?&=?( char signed *, char signed ),			?&=?( volatile char signed *, char signed );
-char unsigned		?&=?( char unsigned *, char unsigned ),			?&=?( volatile char unsigned *, char unsigned );
-int short		?&=?( int short *, int short ),				?&=?( volatile int short *, int short );
-int short unsigned	?&=?( int short unsigned *, int short unsigned ),	?&=?( volatile int short unsigned *, int short unsigned );
-signed int		?&=?( signed int *, signed int ),			?&=?( volatile signed int *, signed int );
-unsigned int		?&=?( unsigned *, unsigned ),				?&=?( volatile unsigned *, unsigned );
-signed long int		?&=?( signed long int *, signed long int ),		?&=?( volatile signed long int *, signed long int );
-unsigned long int	?&=?( unsigned long int *, unsigned long int ),		?&=?( volatile unsigned long int *, unsigned long int );
-signed long long int	?&=?( signed long long int *, signed long long int ),	?&=?( volatile signed long long int *, signed long long int );
-unsigned long long int	?&=?( unsigned long long int *, unsigned long long int ), ?&=?( volatile unsigned long long int *, unsigned long long int );
-
-_Bool			?|=?( _Bool *, _Bool ),					?|=?( volatile _Bool *, _Bool );
-char			?|=?( char *, char ),					?|=?( volatile char *, char );
-char signed		?|=?( char signed *, char signed ),			?|=?( volatile char signed *, char signed );
-char unsigned		?|=?( char unsigned *, char unsigned ),			?|=?( volatile char unsigned *, char unsigned );
-int short		?|=?( int short *, int short ),				?|=?( volatile int short *, int short );
-int short unsigned	?|=?( int short unsigned *, int short unsigned ),	?|=?( volatile int short unsigned *, int short unsigned );
-signed int		?|=?( signed int *, signed int ),			?|=?( volatile signed int *, signed int );
-unsigned int		?|=?( unsigned *, unsigned ),				?|=?( volatile unsigned *, unsigned );
-signed long int		?|=?( signed long int *, signed long int ),		?|=?( volatile signed long int *, signed long int );
-unsigned long int	?|=?( unsigned long int *, unsigned long int ),		?|=?( volatile unsigned long int *, unsigned long int );
-signed long long int	?|=?( signed long long int *, signed long long int ),	?|=?( volatile signed long long int *, signed long long int );
-unsigned long long int	?|=?( unsigned long long int *, unsigned long long int ), ?|=?( volatile unsigned long long int *, unsigned long long int );
-
-_Bool			?^=?( _Bool *, _Bool ),					?^=?( volatile _Bool *, _Bool );
-char			?^=?( char *, char ),					?^=?( volatile char *, char );
-char signed		?^=?( char signed *, char signed ),			?^=?( volatile char signed *, char signed );
-char unsigned		?^=?( char unsigned *, char unsigned ),			?^=?( volatile char unsigned *, char unsigned );
-int short		?^=?( int short *, int short ),				?^=?( volatile int short *, int short );
-int short unsigned	?^=?( int short unsigned *, int short unsigned ),	?^=?( volatile int short unsigned *, int short unsigned );
-signed int		?^=?( signed int *, signed int ),			?^=?( volatile signed int *, signed int );
-unsigned int		?^=?( unsigned *, unsigned ),				?^=?( volatile unsigned *, unsigned );
-signed long int		?^=?( signed long int *, signed long int ),		?^=?( volatile signed long int *, signed long int );
-unsigned long int	?^=?( unsigned long int *, unsigned long int ),		?^=?( volatile unsigned long int *, unsigned long int );
-signed long long int	?^=?( signed long long int *, signed long long int ),	?^=?( volatile signed long long int *, signed long long int );
-unsigned long long int	?^=?( unsigned long long int *, unsigned long long int ), ?^=?( volatile unsigned long long int *, unsigned long long int );
-
-float			?=?(  float *, float ), ?=?(  volatile float *, float ),
-			?*=?( float *, float ), ?*=?( volatile float *, float ),
-			?/=?( float *, float ), ?/=?( volatile float *, float ),
-			?+=?( float *, float ), ?+=?( volatile float *, float ),
-			?-=?( float *, float ), ?-=?( volatile float *, float );
-
-double			?=?(  double *, double ), ?=?(  volatile double *, double ),
-			?*=?( double *, double ), ?*=?( volatile double *, double ),
-			?/=?( double *, double ), ?/=?( volatile double *, double ),
-			?+=?( double *, double ), ?+=?( volatile double *, double ),
-			?-=?( double *, double ), ?-=?( volatile double *, double );
-
-long double		?=?(  long double *, long double ), ?=?(  volatile long double *, long double ),
-			?*=?( long double *, long double ), ?*=?( volatile long double *, long double ),
-			?/=?( long double *, long double ), ?/=?( volatile long double *, long double ),
-			?+=?( long double *, long double ), ?+=?( volatile long double *, long double ),
-			?-=?( long double *, long double ), ?-=?( volatile long double *, long double );
-
-float _Complex		?=?(  float _Complex *, float _Complex ), ?=?(  volatile float _Complex *, float _Complex ),
-			?*=?( float _Complex *, float _Complex ), ?*=?( volatile float _Complex *, float _Complex ),
-			?/=?( float _Complex *, float _Complex ), ?/=?( volatile float _Complex *, float _Complex ),
-			?+=?( float _Complex *, float _Complex ), ?+=?( volatile float _Complex *, float _Complex ),
-			?-=?( float _Complex *, float _Complex ), ?-=?( volatile float _Complex *, float _Complex );
-
-double _Complex		?=?(  double _Complex *, double _Complex ), ?=?(  volatile double _Complex *, double _Complex ),
-			?*=?( double _Complex *, double _Complex ), ?*=?( volatile double _Complex *, double _Complex ),
-			?/=?( double _Complex *, double _Complex ), ?/=?( volatile double _Complex *, double _Complex ),
-			?+=?( double _Complex *, double _Complex ), ?+=?( volatile double _Complex *, double _Complex ),
-			?-=?( double _Complex *, double _Complex ), ?-=?( volatile double _Complex *, double _Complex );
-
-long double _Complex	?=?(  long double _Complex *, long double _Complex ), ?=?(  volatile long double _Complex *, long double _Complex ),
-			?*=?( long double _Complex *, long double _Complex ), ?*=?( volatile long double _Complex *, long double _Complex ),
-			?/=?( long double _Complex *, long double _Complex ), ?/=?( volatile long double _Complex *, long double _Complex ),
-			?+=?( long double _Complex *, long double _Complex ), ?+=?( volatile long double _Complex *, long double _Complex ),
-			?-=?( long double _Complex *, long double _Complex ), ?-=?( volatile long double _Complex *, long double _Complex );
+forall( ftype FT ) FT *			?=?( FT *&, FT * );
+forall( ftype FT ) FT *			?=?( FT * volatile &, FT * );
+
+forall( dtype DT ) DT *			?=?(		     DT *	   &,			DT * );
+forall( dtype DT ) DT *			?=?(		     DT * volatile &,			DT * );
+forall( dtype DT ) const DT *		?=?( const	     DT *	   &,			DT * );
+forall( dtype DT ) const DT *		?=?( const	     DT * volatile &,			DT * );
+forall( dtype DT ) const DT *		?=?( const	     DT *	   &, const		DT * );
+forall( dtype DT ) const DT *		?=?( const	     DT * volatile &, const		DT * );
+forall( dtype DT ) volatile DT *	?=?(	   volatile  DT *	   &,			DT * );
+forall( dtype DT ) volatile DT *	?=?(	   volatile  DT * volatile &,			DT * );
+forall( dtype DT ) volatile DT *	?=?(	   volatile  DT *	   &,	    volatile	DT * );
+forall( dtype DT ) volatile DT *	?=?(	   volatile  DT * volatile &,	    volatile	DT * );
+
+forall( dtype DT ) const volatile DT *	?=?( const volatile  DT *	   &,			DT * );
+forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT * volatile &,			DT * );
+forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT *	   &, const		DT * );
+forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT * volatile &, const		DT * );
+forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT *	   &,	    volatile	DT * );
+forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT * volatile &,	    volatile	DT * );
+forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT *	   &, const volatile	DT * );
+forall( dtype DT ) const volatile DT *  ?=?( const volatile  DT * volatile &, const volatile	DT * );
+
+forall( dtype DT ) DT *			?=?(		     DT *	   &,			void * );
+forall( dtype DT ) DT *			?=?(		     DT * volatile &,			void * );
+forall( dtype DT ) const DT *		?=?( const	     DT *	   &,			void * );
+forall( dtype DT ) const DT *		?=?( const	     DT * volatile &,			void * );
+forall( dtype DT ) const DT *		?=?( const	     DT *	   &, const		void * );
+forall( dtype DT ) const DT *		?=?( const	     DT * volatile &, const		void * );
+forall( dtype DT ) volatile DT *	?=?(	   volatile  DT *	   &,			void * );
+forall( dtype DT ) volatile DT *	?=?(	   volatile  DT * volatile &,			void * );
+forall( dtype DT ) volatile DT *	?=?(	   volatile  DT *	   &,	    volatile	void * );
+forall( dtype DT ) volatile DT *	?=?(	   volatile  DT * volatile &,	    volatile	void * );
+
+forall( dtype DT ) const volatile DT *	?=?( const volatile  DT *	   &,			void * );
+forall( dtype DT ) const volatile DT *	?=?( const volatile  DT * volatile &,			void * );
+forall( dtype DT ) const volatile DT *	?=?( const volatile  DT *	   &, const		void * );
+forall( dtype DT ) const volatile DT *	?=?( const volatile  DT * volatile &, const		void * );
+forall( dtype DT ) const volatile DT *	?=?( const volatile  DT *	   &,	    volatile	void * );
+forall( dtype DT ) const volatile DT *	?=?( const volatile  DT * volatile &,	    volatile	void * );
+forall( dtype DT ) const volatile DT *	?=?( const volatile  DT *	   &, const volatile	void * );
+forall( dtype DT ) const volatile DT *	?=?( const volatile  DT * volatile &, const volatile	void * );
+
+forall( dtype DT ) void *		 ?=?(		     void *	     &,			DT * );
+forall( dtype DT ) void *		 ?=?(		     void * volatile &,			DT * );
+forall( dtype DT ) const void *		 ?=?( const	     void *	     &,			DT * );
+forall( dtype DT ) const void *		 ?=?( const	     void * volatile &,			DT * );
+forall( dtype DT ) const void *		 ?=?( const	     void *	     &, const		DT * );
+forall( dtype DT ) const void *		 ?=?( const	     void * volatile &, const		DT * );
+forall( dtype DT ) volatile void *	 ?=?(	    volatile void *	     &,			DT * );
+forall( dtype DT ) volatile void *	 ?=?(	    volatile void * volatile &,			DT * );
+forall( dtype DT ) volatile void *	 ?=?(	    volatile void *	     &,	      volatile	DT * );
+forall( dtype DT ) volatile void *	 ?=?(	    volatile void * volatile &,	      volatile	DT * );
+forall( dtype DT ) const volatile void * ?=?( const volatile void *	     &,			DT * );
+forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &,			DT * );
+forall( dtype DT ) const volatile void * ?=?( const volatile void *	     &, const		DT * );
+forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &, const		DT * );
+forall( dtype DT ) const volatile void * ?=?( const volatile void *	     &,	      volatile	DT * );
+forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &,	      volatile	DT * );
+forall( dtype DT ) const volatile void * ?=?( const volatile void *	     &, const volatile	DT * );
+forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &, const volatile	DT * );
+
+void *			?=?(		    void *	    &,		      void * );
+void *			?=?(		    void * volatile &,		      void * );
+const void *		?=?( const	    void *	    &,		      void * );
+const void *		?=?( const	    void * volatile &,		      void * );
+const void *		?=?( const	    void *	    &, const	      void * );
+const void *		?=?( const	    void * volatile &, const	      void * );
+volatile void *		?=?(	   volatile void *	    &,		      void * );
+volatile void *		?=?(	   volatile void * volatile &,		      void * );
+volatile void *		?=?(	   volatile void *	    &,	     volatile void * );
+volatile void *		?=?(	   volatile void * volatile &,	     volatile void * );
+const volatile void *	?=?( const volatile void *	    &,		      void * );
+const volatile void *	?=?( const volatile void * volatile &,		      void * );
+const volatile void *	?=?( const volatile void *	    &, const	      void * );
+const volatile void *	?=?( const volatile void * volatile &, const	      void * );
+const volatile void *	?=?( const volatile void *	    &,	     volatile void * );
+const volatile void *	?=?( const volatile void * volatile &,	     volatile void * );
+const volatile void *	?=?( const volatile void *	    &, const volatile void * );
+const volatile void *	?=?( const volatile void * volatile &, const volatile void * );
+
+//forall( dtype DT ) DT *			?=?(		    DT *	  &, forall( dtype DT2 ) const DT2 * );
+//forall( dtype DT ) DT *			?=?(		    DT * volatile &, forall( dtype DT2 ) const DT2 * );
+forall( dtype DT ) const DT *		?=?( const	    DT *	  &, forall( dtype DT2 ) const DT2 * );
+forall( dtype DT ) const DT *		?=?( const	    DT * volatile &, forall( dtype DT2 ) const DT2 * );
+//forall( dtype DT ) volatile DT *	?=?( volatile	    DT *	  &, forall( dtype DT2 ) const DT2 * );
+//forall( dtype DT ) volatile DT *	?=?( volatile	    DT * volatile &, forall( dtype DT2 ) const DT2 * );
+forall( dtype DT ) const volatile DT *	?=?( const volatile DT *	  &, forall( dtype DT2 ) const DT2 * );
+forall( dtype DT ) const volatile DT *	?=?( const volatile DT * volatile &, forall( dtype DT2 ) const DT2 * );
+
+forall( ftype FT ) FT *			?=?( FT *	   &, forall( ftype FT2 ) FT2 * );
+forall( ftype FT ) FT *			?=?( FT * volatile &, forall( ftype FT2 ) FT2 * );
+
+forall( dtype T | sized(T) ) T *			?+=?(		     T *	  &, ptrdiff_t );
+forall( dtype T | sized(T) ) T *			?+=?(		     T * volatile &, ptrdiff_t );
+forall( dtype T | sized(T) ) const T *		?+=?( const	     T *	  &, ptrdiff_t );
+forall( dtype T | sized(T) ) const T *		?+=?( const	     T * volatile &, ptrdiff_t );
+forall( dtype T | sized(T) ) volatile T *		?+=?(	    volatile T *	  &, ptrdiff_t );
+forall( dtype T | sized(T) ) volatile T *		?+=?(	    volatile T * volatile &, ptrdiff_t );
+forall( dtype T | sized(T) ) const volatile T *	?+=?( const volatile T *	  &, ptrdiff_t );
+forall( dtype T | sized(T) ) const volatile T *	?+=?( const volatile T * volatile &, ptrdiff_t );
+forall( dtype T | sized(T) ) T *			?-=?(		     T *	  &, ptrdiff_t );
+forall( dtype T | sized(T) ) T *			?-=?(		     T * volatile &, ptrdiff_t );
+forall( dtype T | sized(T) ) const T *		?-=?( const	     T *	  &, ptrdiff_t );
+forall( dtype T | sized(T) ) const T *		?-=?( const	     T * volatile &, ptrdiff_t );
+forall( dtype T | sized(T) ) volatile T *		?-=?(	    volatile T *	  &, ptrdiff_t );
+forall( dtype T | sized(T) ) volatile T *		?-=?(	    volatile T * volatile &, ptrdiff_t );
+forall( dtype T | sized(T) ) const volatile T *	?-=?( const volatile T *	  &, ptrdiff_t );
+forall( dtype T | sized(T) ) const volatile T *	?-=?( const volatile T * volatile &, ptrdiff_t );
+
+_Bool			?=?( _Bool &, _Bool ),					?=?( volatile _Bool &, _Bool );
+char			?=?( char &, char ),					?=?( volatile char &, char );
+char signed		?=?( char signed &, char signed ),			?=?( volatile char signed &, char signed );
+char unsigned		?=?( char unsigned &, char unsigned ),			?=?( volatile char unsigned &, char unsigned );
+int short		?=?( int short &, int short ),				?=?( volatile int short &, int short );
+int short unsigned	?=?( int short unsigned &, int short unsigned ),	?=?( volatile int short unsigned &, int short unsigned );
+signed int		?=?( signed int &, signed int ),			?=?( volatile signed int &, signed int );
+unsigned int		?=?( unsigned &, unsigned ),				?=?( volatile unsigned &, unsigned );
+signed long int		?=?( signed long int &, signed long int ),		?=?( volatile signed long int &, signed long int );
+unsigned long int	?=?( unsigned long int &, unsigned long int ),		?=?( volatile unsigned long int &, unsigned long int );
+signed long long int	?=?( signed long long int &, signed long long int ),	?=?( volatile signed long long int &, signed long long int );
+unsigned long long int	?=?( unsigned long long int &, unsigned long long int ), ?=?( volatile unsigned long long int &, unsigned long long int );
+zero_t		?=?( zero_t &, zero_t );
+one_t			?=?( one_t &, one_t );
+
+
+_Bool			?*=?( _Bool &, _Bool ),					?*=?( volatile _Bool &, _Bool );
+char			?*=?( char &, char ),					?*=?( volatile char &, char );
+char signed		?*=?( char signed &, char signed ),			?*=?( volatile char signed &, char signed );
+char unsigned		?*=?( char unsigned &, char unsigned ),			?*=?( volatile char unsigned &, char unsigned );
+int short		?*=?( int short &, int short ),				?*=?( volatile int short &, int short );
+int short unsigned	?*=?( int short unsigned &, int short unsigned ),	?*=?( volatile int short unsigned &, int short unsigned );
+signed int		?*=?( signed int &, signed int ),			?*=?( volatile signed int &, signed int );
+unsigned int		?*=?( unsigned &, unsigned ),				?*=?( volatile unsigned &, unsigned );
+signed long int		?*=?( signed long int &, signed long int ),		?*=?( volatile signed long int &, signed long int );
+unsigned long int	?*=?( unsigned long int &, unsigned long int ),		?*=?( volatile unsigned long int &, unsigned long int );
+signed long long int	?*=?( signed long long int &, signed long long int ),	?*=?( volatile signed long long int &, signed long long int );
+unsigned long long int	?*=?( unsigned long long int &, unsigned long long int ), ?*=?( volatile unsigned long long int &, unsigned long long int );
+
+_Bool			?/=?( _Bool &, _Bool ),					?/=?( volatile _Bool &, _Bool );
+char			?/=?( char &, char ),					?/=?( volatile char &, char );
+char signed		?/=?( char signed &, char signed ),			?/=?( volatile char signed &, char signed );
+char unsigned		?/=?( char unsigned &, char unsigned ),			?/=?( volatile char unsigned &, char unsigned );
+int short		?/=?( int short &, int short ),				?/=?( volatile int short &, int short );
+int short unsigned	?/=?( int short unsigned &, int short unsigned ),	?/=?( volatile int short unsigned &, int short unsigned );
+signed int		?/=?( signed int &, signed int ),			?/=?( volatile signed int &, signed int );
+unsigned int		?/=?( unsigned &, unsigned ),				?/=?( volatile unsigned &, unsigned );
+signed long int		?/=?( signed long int &, signed long int ),		?/=?( volatile signed long int &, signed long int );
+unsigned long int	?/=?( unsigned long int &, unsigned long int ),		?/=?( volatile unsigned long int &, unsigned long int );
+signed long long int	?/=?( signed long long int &, signed long long int ),	?/=?( volatile signed long long int &, signed long long int );
+unsigned long long int	?/=?( unsigned long long int &, unsigned long long int ), ?/=?( volatile unsigned long long int &, unsigned long long int );
+
+_Bool			?%=?( _Bool &, _Bool ),					?%=?( volatile _Bool &, _Bool );
+char			?%=?( char &, char ),					?%=?( volatile char &, char );
+char signed		?%=?( char signed &, char signed ),			?%=?( volatile char signed &, char signed );
+char unsigned		?%=?( char unsigned &, char unsigned ),			?%=?( volatile char unsigned &, char unsigned );
+int short		?%=?( int short &, int short ),				?%=?( volatile int short &, int short );
+int short unsigned	?%=?( int short unsigned &, int short unsigned ),	?%=?( volatile int short unsigned &, int short unsigned );
+signed int		?%=?( signed int &, signed int ),			?%=?( volatile signed int &, signed int );
+unsigned int		?%=?( unsigned &, unsigned ),				?%=?( volatile unsigned &, unsigned );
+signed long int		?%=?( signed long int &, signed long int ),		?%=?( volatile signed long int &, signed long int );
+unsigned long int	?%=?( unsigned long int &, unsigned long int ),		?%=?( volatile unsigned long int &, unsigned long int );
+signed long long int	?%=?( signed long long int &, signed long long int ),	?%=?( volatile signed long long int &, signed long long int );
+unsigned long long int	?%=?( unsigned long long int &, unsigned long long int ), ?%=?( volatile unsigned long long int &, unsigned long long int );
+
+_Bool			?+=?( _Bool &, _Bool ),					?+=?( volatile _Bool &, _Bool );
+char			?+=?( char &, char ),					?+=?( volatile char &, char );
+char signed		?+=?( char signed &, char signed ),			?+=?( volatile char signed &, char signed );
+char unsigned		?+=?( char unsigned &, char unsigned ),			?+=?( volatile char unsigned &, char unsigned );
+int short		?+=?( int short &, int short ),				?+=?( volatile int short &, int short );
+int short unsigned	?+=?( int short unsigned &, int short unsigned ),	?+=?( volatile int short unsigned &, int short unsigned );
+signed int		?+=?( signed int &, signed int ),			?+=?( volatile signed int &, signed int );
+unsigned int		?+=?( unsigned &, unsigned ),				?+=?( volatile unsigned &, unsigned );
+signed long int		?+=?( signed long int &, signed long int ),		?+=?( volatile signed long int &, signed long int );
+unsigned long int	?+=?( unsigned long int &, unsigned long int ),		?+=?( volatile unsigned long int &, unsigned long int );
+signed long long int	?+=?( signed long long int &, signed long long int ),	?+=?( volatile signed long long int &, signed long long int );
+unsigned long long int	?+=?( unsigned long long int &, unsigned long long int ), ?+=?( volatile unsigned long long int &, unsigned long long int );
+
+_Bool			?-=?( _Bool &, _Bool ),					?-=?( volatile _Bool &, _Bool );
+char			?-=?( char &, char ),					?-=?( volatile char &, char );
+char signed		?-=?( char signed &, char signed ),			?-=?( volatile char signed &, char signed );
+char unsigned		?-=?( char unsigned &, char unsigned ),			?-=?( volatile char unsigned &, char unsigned );
+int short		?-=?( int short &, int short ),				?-=?( volatile int short &, int short );
+int short unsigned	?-=?( int short unsigned &, int short unsigned ),	?-=?( volatile int short unsigned &, int short unsigned );
+signed int		?-=?( signed int &, signed int ),			?-=?( volatile signed int &, signed int );
+unsigned int		?-=?( unsigned &, unsigned ),				?-=?( volatile unsigned &, unsigned );
+signed long int		?-=?( signed long int &, signed long int ),		?-=?( volatile signed long int &, signed long int );
+unsigned long int	?-=?( unsigned long int &, unsigned long int ),		?-=?( volatile unsigned long int &, unsigned long int );
+signed long long int	?-=?( signed long long int &, signed long long int ),	?-=?( volatile signed long long int &, signed long long int );
+unsigned long long int	?-=?( unsigned long long int &, unsigned long long int ), ?-=?( volatile unsigned long long int &, unsigned long long int );
+
+_Bool			?<<=?( _Bool &, _Bool ),				?<<=?( volatile _Bool &, _Bool );
+char			?<<=?( char &, char ),					?<<=?( volatile char &, char );
+char signed		?<<=?( char signed &, char signed ),			?<<=?( volatile char signed &, char signed );
+char unsigned		?<<=?( char unsigned &, char unsigned ),		?<<=?( volatile char unsigned &, char unsigned );
+int short		?<<=?( int short &, int short ),			?<<=?( volatile int short &, int short );
+int short unsigned	?<<=?( int short unsigned &, int short unsigned ),	?<<=?( volatile int short unsigned &, int short unsigned );
+signed int		?<<=?( signed int &, signed int ),			?<<=?( volatile signed int &, signed int );
+unsigned int		?<<=?( unsigned &, unsigned ),				?<<=?( volatile unsigned &, unsigned );
+signed long int		?<<=?( signed long int &, signed long int ),		?<<=?( volatile signed long int &, signed long int );
+unsigned long int	?<<=?( unsigned long int &, unsigned long int ),	?<<=?( volatile unsigned long int &, unsigned long int );
+signed long long int	?<<=?( signed long long int &, signed long long int ),	?<<=?( volatile signed long long int &, signed long long int );
+unsigned long long int	?<<=?( unsigned long long int &, unsigned long long int ), ?<<=?( volatile unsigned long long int &, unsigned long long int );
+
+_Bool			?>>=?( _Bool &, _Bool ),				?>>=?( volatile _Bool &, _Bool );
+char			?>>=?( char &, char ),					?>>=?( volatile char &, char );
+char signed		?>>=?( char signed &, char signed ),			?>>=?( volatile char signed &, char signed );
+char unsigned		?>>=?( char unsigned &, char unsigned ),		?>>=?( volatile char unsigned &, char unsigned );
+int short		?>>=?( int short &, int short ),			?>>=?( volatile int short &, int short );
+int short unsigned	?>>=?( int short unsigned &, int short unsigned ),	?>>=?( volatile int short unsigned &, int short unsigned );
+signed int		?>>=?( signed int &, signed int ),			?>>=?( volatile signed int &, signed int );
+unsigned int		?>>=?( unsigned &, unsigned ),				?>>=?( volatile unsigned &, unsigned );
+signed long int		?>>=?( signed long int &, signed long int ),		?>>=?( volatile signed long int &, signed long int );
+unsigned long int	?>>=?( unsigned long int &, unsigned long int ),	?>>=?( volatile unsigned long int &, unsigned long int );
+signed long long int	?>>=?( signed long long int &, signed long long int ),	?>>=?( volatile signed long long int &, signed long long int );
+unsigned long long int	?>>=?( unsigned long long int &, unsigned long long int ), ?>>=?( volatile unsigned long long int &, unsigned long long int );
+
+_Bool			?&=?( _Bool &, _Bool ),					?&=?( volatile _Bool &, _Bool );
+char			?&=?( char &, char ),					?&=?( volatile char &, char );
+char signed		?&=?( char signed &, char signed ),			?&=?( volatile char signed &, char signed );
+char unsigned		?&=?( char unsigned &, char unsigned ),			?&=?( volatile char unsigned &, char unsigned );
+int short		?&=?( int short &, int short ),				?&=?( volatile int short &, int short );
+int short unsigned	?&=?( int short unsigned &, int short unsigned ),	?&=?( volatile int short unsigned &, int short unsigned );
+signed int		?&=?( signed int &, signed int ),			?&=?( volatile signed int &, signed int );
+unsigned int		?&=?( unsigned &, unsigned ),				?&=?( volatile unsigned &, unsigned );
+signed long int		?&=?( signed long int &, signed long int ),		?&=?( volatile signed long int &, signed long int );
+unsigned long int	?&=?( unsigned long int &, unsigned long int ),		?&=?( volatile unsigned long int &, unsigned long int );
+signed long long int	?&=?( signed long long int &, signed long long int ),	?&=?( volatile signed long long int &, signed long long int );
+unsigned long long int	?&=?( unsigned long long int &, unsigned long long int ), ?&=?( volatile unsigned long long int &, unsigned long long int );
+
+_Bool			?|=?( _Bool &, _Bool ),					?|=?( volatile _Bool &, _Bool );
+char			?|=?( char &, char ),					?|=?( volatile char &, char );
+char signed		?|=?( char signed &, char signed ),			?|=?( volatile char signed &, char signed );
+char unsigned		?|=?( char unsigned &, char unsigned ),			?|=?( volatile char unsigned &, char unsigned );
+int short		?|=?( int short &, int short ),				?|=?( volatile int short &, int short );
+int short unsigned	?|=?( int short unsigned &, int short unsigned ),	?|=?( volatile int short unsigned &, int short unsigned );
+signed int		?|=?( signed int &, signed int ),			?|=?( volatile signed int &, signed int );
+unsigned int		?|=?( unsigned &, unsigned ),				?|=?( volatile unsigned &, unsigned );
+signed long int		?|=?( signed long int &, signed long int ),		?|=?( volatile signed long int &, signed long int );
+unsigned long int	?|=?( unsigned long int &, unsigned long int ),		?|=?( volatile unsigned long int &, unsigned long int );
+signed long long int	?|=?( signed long long int &, signed long long int ),	?|=?( volatile signed long long int &, signed long long int );
+unsigned long long int	?|=?( unsigned long long int &, unsigned long long int ), ?|=?( volatile unsigned long long int &, unsigned long long int );
+
+_Bool			?^=?( _Bool &, _Bool ),					?^=?( volatile _Bool &, _Bool );
+char			?^=?( char &, char ),					?^=?( volatile char &, char );
+char signed		?^=?( char signed &, char signed ),			?^=?( volatile char signed &, char signed );
+char unsigned		?^=?( char unsigned &, char unsigned ),			?^=?( volatile char unsigned &, char unsigned );
+int short		?^=?( int short &, int short ),				?^=?( volatile int short &, int short );
+int short unsigned	?^=?( int short unsigned &, int short unsigned ),	?^=?( volatile int short unsigned &, int short unsigned );
+signed int		?^=?( signed int &, signed int ),			?^=?( volatile signed int &, signed int );
+unsigned int		?^=?( unsigned &, unsigned ),				?^=?( volatile unsigned &, unsigned );
+signed long int		?^=?( signed long int &, signed long int ),		?^=?( volatile signed long int &, signed long int );
+unsigned long int	?^=?( unsigned long int &, unsigned long int ),		?^=?( volatile unsigned long int &, unsigned long int );
+signed long long int	?^=?( signed long long int &, signed long long int ),	?^=?( volatile signed long long int &, signed long long int );
+unsigned long long int	?^=?( unsigned long long int &, unsigned long long int ), ?^=?( volatile unsigned long long int &, unsigned long long int );
+
+float			?=?(  float &, float ), ?=?(  volatile float &, float ),
+			?*=?( float &, float ), ?*=?( volatile float &, float ),
+			?/=?( float &, float ), ?/=?( volatile float &, float ),
+			?+=?( float &, float ), ?+=?( volatile float &, float ),
+			?-=?( float &, float ), ?-=?( volatile float &, float );
+
+double			?=?(  double &, double ), ?=?(  volatile double &, double ),
+			?*=?( double &, double ), ?*=?( volatile double &, double ),
+			?/=?( double &, double ), ?/=?( volatile double &, double ),
+			?+=?( double &, double ), ?+=?( volatile double &, double ),
+			?-=?( double &, double ), ?-=?( volatile double &, double );
+
+long double		?=?(  long double &, long double ), ?=?(  volatile long double &, long double ),
+			?*=?( long double &, long double ), ?*=?( volatile long double &, long double ),
+			?/=?( long double &, long double ), ?/=?( volatile long double &, long double ),
+			?+=?( long double &, long double ), ?+=?( volatile long double &, long double ),
+			?-=?( long double &, long double ), ?-=?( volatile long double &, long double );
+
+float _Complex		?=?(  float _Complex &, float _Complex ), ?=?(  volatile float _Complex &, float _Complex ),
+			?*=?( float _Complex &, float _Complex ), ?*=?( volatile float _Complex &, float _Complex ),
+			?/=?( float _Complex &, float _Complex ), ?/=?( volatile float _Complex &, float _Complex ),
+			?+=?( float _Complex &, float _Complex ), ?+=?( volatile float _Complex &, float _Complex ),
+			?-=?( float _Complex &, float _Complex ), ?-=?( volatile float _Complex &, float _Complex );
+
+double _Complex		?=?(  double _Complex &, double _Complex ), ?=?(  volatile double _Complex &, double _Complex ),
+			?*=?( double _Complex &, double _Complex ), ?*=?( volatile double _Complex &, double _Complex ),
+			?/=?( double _Complex &, double _Complex ), ?/=?( volatile double _Complex &, double _Complex ),
+			?+=?( double _Complex &, double _Complex ), ?+=?( volatile double _Complex &, double _Complex ),
+			?-=?( double _Complex &, double _Complex ), ?-=?( volatile double _Complex &, double _Complex );
+
+long double _Complex	?=?(  long double _Complex &, long double _Complex ), ?=?(  volatile long double _Complex &, long double _Complex ),
+			?*=?( long double _Complex &, long double _Complex ), ?*=?( volatile long double _Complex &, long double _Complex ),
+			?/=?( long double _Complex &, long double _Complex ), ?/=?( volatile long double _Complex &, long double _Complex ),
+			?+=?( long double _Complex &, long double _Complex ), ?+=?( volatile long double _Complex &, long double _Complex ),
+			?-=?( long double _Complex &, long double _Complex ), ?-=?( volatile long double _Complex &, long double _Complex );
 
 
@@ -669,68 +669,68 @@
 
 // default ctor
-void	?{}( _Bool * );
-void	?{}( char * );
-void	?{}( unsigned char * );
-void	?{}( char signed * );
-void	?{}( int short * );
-void	?{}( int short unsigned * );
-void	?{}( signed int * );
-void	?{}( unsigned int * );
-void	?{}( signed long int * );
-void	?{}( unsigned long int * );
-void	?{}( signed long long int * );
-void	?{}( unsigned long long int * );
-void	?{}( float * );
-void	?{}( double * );
-void	?{}( long double * );
-void	?{}( float _Complex * );
-void	?{}( double _Complex * );
-void	?{}( long double _Complex * );
-void	?{}( zero_t * );
-void	?{}( one_t * );
+void	?{}( _Bool & );
+void	?{}( char & );
+void	?{}( unsigned char & );
+void	?{}( char signed & );
+void	?{}( int short & );
+void	?{}( int short unsigned & );
+void	?{}( signed int & );
+void	?{}( unsigned int & );
+void	?{}( signed long int & );
+void	?{}( unsigned long int & );
+void	?{}( signed long long int & );
+void	?{}( unsigned long long int & );
+void	?{}( float & );
+void	?{}( double & );
+void	?{}( long double & );
+void	?{}( float _Complex & );
+void	?{}( double _Complex & );
+void	?{}( long double _Complex & );
+void	?{}( zero_t & );
+void	?{}( one_t & );
 
 // copy ctor
-void	?{}( _Bool *, _Bool );
-void	?{}( char *, char );
-void	?{}( unsigned char *, unsigned char );
-void	?{}( char signed *, char signed );
-void	?{}( int short *, int short );
-void	?{}( int short unsigned *, int short unsigned );
-void	?{}( signed int *, signed int);
-void	?{}( unsigned int *, unsigned int);
-void	?{}( signed long int *, signed long int);
-void	?{}( unsigned long int *, unsigned long int);
-void	?{}( signed long long int *, signed long long int);
-void	?{}( unsigned long long int *, unsigned long long int);
-void	?{}( float *, float);
-void	?{}( double *, double);
-void	?{}( long double *, long double);
-void	?{}( float _Complex *, float _Complex);
-void	?{}( double _Complex *, double _Complex);
-void	?{}( long double _Complex *, long double _Complex);
-void	?{}( zero_t *, zero_t );
-void	?{}( one_t *, one_t );
+void	?{}( _Bool &, _Bool );
+void	?{}( char &, char );
+void	?{}( unsigned char &, unsigned char );
+void	?{}( char signed &, char signed );
+void	?{}( int short &, int short );
+void	?{}( int short unsigned &, int short unsigned );
+void	?{}( signed int &, signed int);
+void	?{}( unsigned int &, unsigned int);
+void	?{}( signed long int &, signed long int);
+void	?{}( unsigned long int &, unsigned long int);
+void	?{}( signed long long int &, signed long long int);
+void	?{}( unsigned long long int &, unsigned long long int);
+void	?{}( float &, float);
+void	?{}( double &, double);
+void	?{}( long double &, long double);
+void	?{}( float _Complex &, float _Complex);
+void	?{}( double _Complex &, double _Complex);
+void	?{}( long double _Complex &, long double _Complex);
+void	?{}( zero_t &, zero_t );
+void	?{}( one_t &, one_t );
 
 // dtor
-void	^?{}( _Bool * );
-void	^?{}( char * );
-void	^?{}( char unsigned * );
-void	^?{}( char signed * );
-void	^?{}( int short * );
-void	^?{}( int short unsigned * );
-void	^?{}( signed int * );
-void	^?{}( unsigned int * );
-void	^?{}( signed long int * );
-void	^?{}( unsigned long int * );
-void	^?{}( signed long long int * );
-void	^?{}( unsigned long long int * );
-void	^?{}( float * );
-void	^?{}( double * );
-void	^?{}( long double * );
-void	^?{}( float _Complex * );
-void	^?{}( double _Complex * );
-void	^?{}( long double _Complex * );
-void	^?{}( zero_t * );
-void	^?{}( one_t * );
+void	^?{}( _Bool & );
+void	^?{}( char & );
+void	^?{}( char unsigned & );
+void	^?{}( char signed & );
+void	^?{}( int short & );
+void	^?{}( int short unsigned & );
+void	^?{}( signed int & );
+void	^?{}( unsigned int & );
+void	^?{}( signed long int & );
+void	^?{}( unsigned long int & );
+void	^?{}( signed long long int & );
+void	^?{}( unsigned long long int & );
+void	^?{}( float & );
+void	^?{}( double & );
+void	^?{}( long double & );
+void	^?{}( float _Complex & );
+void	^?{}( double _Complex & );
+void	^?{}( long double _Complex & );
+void	^?{}( zero_t & );
+void	^?{}( one_t & );
 
 // // default ctor
@@ -754,83 +754,83 @@
 // copied from assignment section
 // copy constructors
-forall( ftype FT ) void ?{}( FT **, FT * );
-forall( ftype FT ) void ?{}( FT * volatile *, FT * );
-
-forall( dtype DT ) void ?{}(		     DT *	   *,			DT * );
-forall( dtype DT ) void ?{}( const	     DT *	   *,			DT * );
-forall( dtype DT ) void ?{}( const	     DT *	   *, const		DT * );
-forall( dtype DT ) void ?{}(	   volatile  DT *	   *,			DT * );
-forall( dtype DT ) void ?{}(	   volatile  DT *	   *,	    volatile	DT * );
-
-forall( dtype DT ) void ?{}( const volatile  DT *	   *,			DT * );
-forall( dtype DT ) void ?{}( const volatile  DT *	   *, const		DT * );
-forall( dtype DT ) void ?{}( const volatile  DT *	   *,	    volatile	DT * );
-forall( dtype DT ) void ?{}( const volatile  DT *	   *, const volatile	DT * );
-
-forall( dtype DT ) void ?{}(		     DT *	   *,			void * );
-forall( dtype DT ) void ?{}( const	     DT *	   *,			void * );
-forall( dtype DT ) void ?{}( const	     DT *	   *, const		void * );
-forall( dtype DT ) void ?{}(	   volatile  DT *	   *,			void * );
-forall( dtype DT ) void ?{}(	   volatile  DT *	   *,	    volatile	void * );
-
-forall( dtype DT ) void ?{}( const volatile  DT *	   *,			void * );
-forall( dtype DT ) void ?{}( const volatile  DT *	   *, const		void * );
-forall( dtype DT ) void ?{}( const volatile  DT *	   *,	    volatile	void * );
-forall( dtype DT ) void ?{}( const volatile  DT *	   *, const volatile	void * );
-
-forall( dtype DT ) void ?{}(		     void *	     *,			DT * );
-forall( dtype DT ) void ?{}( const	     void *	     *,			DT * );
-forall( dtype DT ) void ?{}( const	     void *	     *, const		DT * );
-forall( dtype DT ) void ?{}(	    volatile void *	     *,			DT * );
-forall( dtype DT ) void ?{}(	    volatile void *	     *,	      volatile	DT * );
-forall( dtype DT ) void ?{}( const volatile void *	     *,			DT * );
-forall( dtype DT ) void ?{}( const volatile void *	     *, const		DT * );
-forall( dtype DT ) void ?{}( const volatile void *	     *,	      volatile	DT * );
-forall( dtype DT ) void ?{}( const volatile void *	     *, const volatile	DT * );
-
-void 	?{}(		    void *	    *,		      void * );
-void 	?{}( const	    void *	    *,		      void * );
-void 	?{}( const	    void *	    *, const	      void * );
-void 	?{}(	   volatile void *	    *,		      void * );
-void 	?{}(	   volatile void *	    *,	     volatile void * );
-void 	?{}( const volatile void *	    *,		      void * );
-void 	?{}( const volatile void *	    *, const	      void * );
-void 	?{}( const volatile void *	    *,	     volatile void * );
-void 	?{}( const volatile void *	    *, const volatile void * );
-
-// //forall( dtype DT ) void ?{}(		    DT *	  *, zero_t );
-// //forall( dtype DT ) void ?{}(		    DT * volatile *, zero_t );
-// forall( dtype DT ) void ?{}( const	    DT *	  *, zero_t );
-// //forall( dtype DT ) void ?{}( volatile	    DT *	  *, zero_t );
-// //forall( dtype DT ) void ?{}( volatile	    DT * volatile *, zero_t );
-// forall( dtype DT ) void ?{}( const volatile DT *	  *, zero_t );
-
-// forall( ftype FT ) void	?{}( FT *	   *, zero_t );
+forall( ftype FT ) void ?{}( FT *&, FT * );
+forall( ftype FT ) void ?{}( FT * volatile &, FT * );
+
+forall( dtype DT ) void ?{}(		     DT *	   &,			DT * );
+forall( dtype DT ) void ?{}( const	     DT *	   &,			DT * );
+forall( dtype DT ) void ?{}( const	     DT *	   &, const		DT * );
+forall( dtype DT ) void ?{}(	   volatile  DT *	   &,			DT * );
+forall( dtype DT ) void ?{}(	   volatile  DT *	   &,	    volatile	DT * );
+
+forall( dtype DT ) void ?{}( const volatile  DT *	   &,			DT * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   &, const		DT * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   &,	    volatile	DT * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   &, const volatile	DT * );
+
+forall( dtype DT ) void ?{}(		     DT *	   &,			void * );
+forall( dtype DT ) void ?{}( const	     DT *	   &,			void * );
+forall( dtype DT ) void ?{}( const	     DT *	   &, const		void * );
+forall( dtype DT ) void ?{}(	   volatile  DT *	   &,			void * );
+forall( dtype DT ) void ?{}(	   volatile  DT *	   &,	    volatile	void * );
+
+forall( dtype DT ) void ?{}( const volatile  DT *	   &,			void * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   &, const		void * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   &,	    volatile	void * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   &, const volatile	void * );
+
+forall( dtype DT ) void ?{}(		     void *	     &,			DT * );
+forall( dtype DT ) void ?{}( const	     void *	     &,			DT * );
+forall( dtype DT ) void ?{}( const	     void *	     &, const		DT * );
+forall( dtype DT ) void ?{}(	    volatile void *	     &,			DT * );
+forall( dtype DT ) void ?{}(	    volatile void *	     &,	      volatile	DT * );
+forall( dtype DT ) void ?{}( const volatile void *	     &,			DT * );
+forall( dtype DT ) void ?{}( const volatile void *	     &, const		DT * );
+forall( dtype DT ) void ?{}( const volatile void *	     &,	      volatile	DT * );
+forall( dtype DT ) void ?{}( const volatile void *	     &, const volatile	DT * );
+
+void 	?{}(		    void *	    &,		      void * );
+void 	?{}( const	    void *	    &,		      void * );
+void 	?{}( const	    void *	    &, const	      void * );
+void 	?{}(	   volatile void *	    &,		      void * );
+void 	?{}(	   volatile void *	    &,	     volatile void * );
+void 	?{}( const volatile void *	    &,		      void * );
+void 	?{}( const volatile void *	    &, const	      void * );
+void 	?{}( const volatile void *	    &,	     volatile void * );
+void 	?{}( const volatile void *	    &, const volatile void * );
+
+//forall( dtype DT ) void ?{}(		    DT *	  &, forall( dtype DT2 ) const DT2 * );
+//forall( dtype DT ) void ?{}(		    DT * volatile &, forall( dtype DT2 ) const DT2 * );
+forall( dtype DT ) void ?{}( const	    DT *	  &, forall( dtype DT2 ) const DT2 * );
+//forall( dtype DT ) void ?{}( volatile	    DT *	  &, forall( dtype DT2 ) const DT2 * );
+//forall( dtype DT ) void ?{}( volatile	    DT * volatile &, forall( dtype DT2 ) const DT2 * );
+forall( dtype DT ) void ?{}( const volatile DT *	  &, forall( dtype DT2 ) const DT2 * );
+
+forall( ftype FT ) void	?{}( FT *	   &, forall( ftype FT2 ) FT2 * );
 
 // default ctors
-forall( ftype FT ) void	?{}( FT *	   * );
-
-forall( dtype DT ) void	?{}(		     DT *	   *);
-forall( dtype DT ) void	?{}( const	     DT *	   *);
-forall( dtype DT ) void	?{}(	   volatile  DT *	   *);
-forall( dtype DT ) void ?{}( const volatile  DT *	   *);
-
-void 	?{}(		    void *	    *);
-void 	?{}( const	    void *	    *);
-void 	?{}(	   volatile void *	    *);
-void 	?{}( const volatile void *	    *);
+forall( ftype FT ) void	?{}( FT *	   & );
+
+forall( dtype DT ) void	?{}(		     DT *	   &);
+forall( dtype DT ) void	?{}( const	     DT *	   &);
+forall( dtype DT ) void	?{}(	   volatile  DT *	   &);
+forall( dtype DT ) void ?{}( const volatile  DT *	   &);
+
+void 	?{}(		    void *	    &);
+void 	?{}( const	    void *	    &);
+void 	?{}(	   volatile void *	    &);
+void 	?{}( const volatile void *	    &);
 
 // dtors
-forall( ftype FT ) void	^?{}( FT *	   * );
-
-forall( dtype DT ) void	^?{}(		     DT *	   *);
-forall( dtype DT ) void	^?{}( const	     DT *	   *);
-forall( dtype DT ) void	^?{}(	   volatile  DT *	   *);
-forall( dtype DT ) void ^?{}( const volatile  DT *	   *);
-
-void 	^?{}(		    void *	    *);
-void 	^?{}( const	    void *	    *);
-void 	^?{}(	   volatile void *	    *);
-void 	^?{}( const volatile void *	    *);
+forall( ftype FT ) void	^?{}( FT *	   & );
+
+forall( dtype DT ) void	^?{}(		     DT *	   &);
+forall( dtype DT ) void	^?{}( const	     DT *	   &);
+forall( dtype DT ) void	^?{}(	   volatile  DT *	   &);
+forall( dtype DT ) void ^?{}( const volatile  DT *	   &);
+
+void 	^?{}(		    void *	    &);
+void 	^?{}( const	    void *	    &);
+void 	^?{}(	   volatile void *	    &);
+void 	^?{}( const volatile void *	    &);
 
 // Local Variables: //
