Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/CodeGen/CodeGenerator.cc	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -203,6 +203,4 @@
 
 	void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) {
-		genAttributes( aggDecl->get_attributes() );
-
 		if( ! aggDecl->get_parameters().empty() && ! genC ) {
 			// assertf( ! genC, "Aggregate type parameters should not reach code generation." );
@@ -213,5 +211,7 @@
 		}
 
-		output << kind << aggDecl->get_name();
+		output << kind;
+		genAttributes( aggDecl->get_attributes() );
+		output << aggDecl->get_name();
 
 		if ( aggDecl->has_body() ) {
@@ -298,4 +298,12 @@
 			output << " }";
 		}
+	}
+
+	void CodeGenerator::postvisit( StaticAssertDecl * assertDecl ) {
+		output << "_Static_assert(";
+		assertDecl->condition->accept( *visitor );
+		output << ", ";
+		assertDecl->message->accept( *visitor );
+		output << ")";
 	}
 
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/CodeGen/CodeGenerator.h	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -42,9 +42,10 @@
 		void postvisit( FunctionDecl * );
 		void postvisit( ObjectDecl * );
-		void postvisit( UnionDecl *aggregateDecl );
-		void postvisit( EnumDecl *aggregateDecl );
-		void postvisit( TraitDecl *aggregateDecl );
-		void postvisit( TypedefDecl *typeDecl );
-		void postvisit( TypeDecl *typeDecl );
+		void postvisit( UnionDecl * aggregateDecl );
+		void postvisit( EnumDecl * aggregateDecl );
+		void postvisit( TraitDecl * aggregateDecl );
+		void postvisit( TypedefDecl * typeDecl );
+		void postvisit( TypeDecl * typeDecl );
+		void postvisit( StaticAssertDecl * assertDecl );
 
 		//*** Initializer
Index: src/CodeGen/OperatorTable.cc
===================================================================
--- src/CodeGen/OperatorTable.cc	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/CodeGen/OperatorTable.cc	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -79,5 +79,5 @@
 	} // namespace
 
-	bool operatorLookup( std::string funcName, OperatorInfo &info ) {
+	bool operatorLookup( const std::string & funcName, OperatorInfo & info ) {
 		static bool init = false;
 		if ( ! init ) {
@@ -100,4 +100,9 @@
 			return true;
 		} // if
+	}
+
+	bool isOperator( const std::string & funcName ) {
+		OperatorInfo info;
+		return operatorLookup( funcName, info );
 	}
 
Index: src/CodeGen/OperatorTable.h
===================================================================
--- src/CodeGen/OperatorTable.h	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/CodeGen/OperatorTable.h	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -41,5 +41,6 @@
 	};
 
-	bool operatorLookup( std::string funcName, OperatorInfo &info );
+	bool isOperator( const std::string & funcName );
+	bool operatorLookup( const std::string & funcName, OperatorInfo & info );
 
 	bool isConstructor( const std::string & );
Index: src/Common/Debug.h
===================================================================
--- src/Common/Debug.h	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/Common/Debug.h	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -28,5 +28,5 @@
 namespace Debug {
 	/// debug codegen a translation unit
-	static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, LinkageSpec::Spec linkageFilter = LinkageSpec::Compiler ) {
+	static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, __attribute__((unused)) LinkageSpec::Spec linkageFilter = LinkageSpec::Compiler ) {
 	#ifdef DEBUG
 		std::list< Declaration * > decls;
@@ -41,5 +41,5 @@
 	} // dump
 
-	static inline void treeDump( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, LinkageSpec::Spec linkageFilter = LinkageSpec::Compiler ) {
+	static inline void treeDump( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, __attribute__((unused)) LinkageSpec::Spec linkageFilter = LinkageSpec::Compiler ) {
 	#ifdef DEBUG
 		std::list< Declaration * > decls;
Index: src/Common/ErrorObjects.h
===================================================================
--- src/Common/ErrorObjects.h	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/Common/ErrorObjects.h	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -35,5 +35,5 @@
 class SemanticErrorException : public std::exception {
   public:
-  	SemanticErrorException() = default;
+	SemanticErrorException() = default;
 	SemanticErrorException( CodeLocation location, std::string error );
 	~SemanticErrorException() throw() {}
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/Common/PassVisitor.h	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -66,4 +66,5 @@
 	virtual void visit( TypedefDecl * typeDecl ) override final;
 	virtual void visit( AsmDecl * asmDecl ) override final;
+	virtual void visit( StaticAssertDecl * assertDecl ) override final;
 
 	virtual void visit( CompoundStmt * compoundStmt ) override final;
@@ -161,4 +162,5 @@
 	virtual Declaration * mutate( TypedefDecl * typeDecl ) override final;
 	virtual AsmDecl * mutate( AsmDecl * asmDecl ) override final;
+	virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) override final;
 
 	virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override final;
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/Common/PassVisitor.impl.h	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -685,4 +685,26 @@
 
 //--------------------------------------------------------------------------
+// StaticAssertDecl
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( StaticAssertDecl * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->condition, *this );
+	maybeAccept_impl( node->message  , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+StaticAssertDecl * PassVisitor< pass_type >::mutate( StaticAssertDecl * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->condition, *this );
+	maybeMutate_impl( node->message  , *this );
+
+	MUTATE_END( StaticAssertDecl, node );
+}
+
+//--------------------------------------------------------------------------
 // CompoundStmt
 template< typename pass_type >
@@ -1490,5 +1512,4 @@
 	indexerScopedAccept( node->result, *this );
 	maybeAccept_impl   ( node->type  , *this );
-	maybeAccept_impl   ( node->member, *this );
 
 	VISIT_END( node );
@@ -1502,5 +1523,4 @@
 	indexerScopedMutate( node->result, *this );
 	maybeMutate_impl   ( node->type  , *this );
-	maybeMutate_impl   ( node->member, *this );
 
 	MUTATE_END( Expression, node );
Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/GenPoly/Lvalue.cc	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -45,4 +45,5 @@
 		Expression * mkDeref( Expression * arg ) {
 			if ( SymTab::dereferenceOperator ) {
+				// note: reference depth can be arbitrarily deep here, so peel off the outermost pointer/reference, not just pointer because they are effecitvely equivalent in this pass
 				VariableExpr * deref = new VariableExpr( SymTab::dereferenceOperator );
 				deref->result = new PointerType( Type::Qualifiers(), deref->result );
@@ -197,18 +198,23 @@
 					PRINT(
 						std::cerr << "pair<0>: " << arg << std::endl;
+						std::cerr << " -- " << arg->result << std::endl;
 						std::cerr << "pair<1>: " << formal << std::endl;
 					)
 					if ( dynamic_cast<ReferenceType*>( formal ) ) {
-						if ( isIntrinsicReference( arg ) ) { // do not combine conditions, because that changes the meaning of the else if
-							if ( function->get_linkage() != LinkageSpec::Intrinsic ) { // intrinsic functions that turn pointers into references
-								// if argument is dereference or array subscript, the result isn't REALLY a reference, so it's not necessary to fix the argument
-								PRINT(
-									std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl;
-								)
-								arg = new AddressExpr( arg );
-							}
-						} else if ( function->get_linkage() == LinkageSpec::Intrinsic ) {
-							// std::cerr << "===adding deref to arg" << std::endl;
-							// if the parameter is a reference, add a dereference to the reference-typed argument.
+						PRINT(
+							std::cerr << "===formal is reference" << std::endl;
+						)
+						// TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation.
+						if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
+							// if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address
+							PRINT(
+								std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl;
+							)
+							arg = new AddressExpr( arg );
+						} else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
+							// argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument
+							PRINT(
+								std::cerr << "===is non-intrinsic arg in intrinsic call - adding deref to arg" << std::endl;
+							)
 							Type * baseType = InitTweak::getPointerBase( arg->result );
 							assertf( baseType, "parameter is reference, arg must be pointer or reference: %s", toString( arg->result ).c_str() );
@@ -217,4 +223,5 @@
 							arg->set_result( ptrType );
 							arg = mkDeref( arg );
+							assertf( arg->result->referenceDepth() == 0, "Reference types should have been eliminated from intrinsic function calls, but weren't: %s", toCString( arg->result ) );
 						}
 					}
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/Parser/DeclarationNode.cc	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -71,4 +71,7 @@
 	attr.expr = nullptr;
 	attr.type = nullptr;
+
+	assert.condition = nullptr;
+	assert.message = nullptr;
 }
 
@@ -88,4 +91,7 @@
 	// asmName, no delete, passed to next stage
 	delete initializer;
+
+	delete assert.condition;
+	delete assert.message;
 }
 
@@ -117,4 +123,7 @@
 	newnode->attr.expr = maybeClone( attr.expr );
 	newnode->attr.type = maybeClone( attr.type );
+
+	newnode->assert.condition = maybeClone( assert.condition );
+	newnode->assert.message = maybeClone( assert.message );
 	return newnode;
 } // DeclarationNode::clone
@@ -434,4 +443,12 @@
 	return newnode;
 }
+
+DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression * message ) {
+	DeclarationNode * newnode = new DeclarationNode;
+	newnode->assert.condition = condition;
+	newnode->assert.message = message;
+	return newnode;
+}
+
 
 void appendError( string & dst, const string & src ) {
@@ -1052,4 +1069,8 @@
 	} // if
 
+	if ( assert.condition ) {
+		return new StaticAssertDecl( maybeBuild< Expression >( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) );
+	}
+
 	// SUE's cannot have function specifiers, either
 	//
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/Parser/ParseNode.h	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -246,4 +246,5 @@
 	static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
 	static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
+	static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
 
 	DeclarationNode();
@@ -313,4 +314,10 @@
 	Attr_t attr;
 
+	struct StaticAssert_t {
+		ExpressionNode * condition;
+		Expression * message;
+	};
+	StaticAssert_t assert;
+
 	BuiltinType builtin;
 
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/Parser/parser.yy	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -1314,5 +1314,5 @@
 static_assert:
 	STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11
-		{ SemanticError( yylloc, "Static assert is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
 
 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/ResolvExpr/CommonType.cc	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -27,5 +27,10 @@
 #include "typeops.h"                     // for isFtype
 
-// #define DEBUG
+#define DEBUG
+#ifdef DEBUG
+#define PRINT(x) x
+#else
+#define PRINT(x)
+#endif
 
 namespace ResolvExpr {
@@ -70,7 +75,11 @@
 		// need unify to bind type variables
 		if ( unify( t1, t2, env, have, need, newOpen, indexer, common ) ) {
-			// std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
+			PRINT(
+				std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
+			)
 			if ( (widenFirst || t2->get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) {
-				// std::cerr << "widen okay" << std::endl;
+				PRINT(
+					std::cerr << "widen okay" << std::endl;
+				)
 				common->get_qualifiers() |= t1->get_qualifiers();
 				common->get_qualifiers() |= t2->get_qualifiers();
@@ -78,5 +87,7 @@
 			}
 		}
-		// std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
+		PRINT(
+			std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
+		)
 		return nullptr;
 	}
@@ -94,5 +105,7 @@
 			// special case where one type has a reference depth of 1 larger than the other
 			if ( diff > 0 || diff < 0 ) {
-				// std::cerr << "reference depth diff: " << diff << std::endl;
+				PRINT(
+					std::cerr << "reference depth diff: " << diff << std::endl;
+				)
 				Type * result = nullptr;
 				ReferenceType * ref1 = dynamic_cast< ReferenceType * >( type1 );
@@ -109,8 +122,12 @@
 				if ( result && ref1 ) {
 					// formal is reference, so result should be reference
-					// std::cerr << "formal is reference; result should be reference" << std::endl;
+					PRINT(
+						std::cerr << "formal is reference; result should be reference" << std::endl;
+					)
 					result = new ReferenceType( ref1->get_qualifiers(), result );
 				}
-				// std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl;
+				PRINT(
+					std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl;
+				)
 				return result;
 			}
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/ResolvExpr/Resolver.cc	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -59,4 +59,5 @@
 		void previsit( TypeDecl *typeDecl );
 		void previsit( EnumDecl * enumDecl );
+		void previsit( StaticAssertDecl * assertDecl );
 
 		void previsit( ArrayType * at );
@@ -361,4 +362,8 @@
 		GuardValue( inEnumDecl );
 		inEnumDecl = true;
+	}
+
+	void Resolver::previsit( StaticAssertDecl * assertDecl ) {
+		findIntegralExpression( assertDecl->condition, indexer );
 	}
 
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/SymTab/Validate.cc	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -89,4 +89,5 @@
 		void previsit( StructDecl * aggregateDecl );
 		void previsit( UnionDecl * aggregateDecl );
+		void previsit( StaticAssertDecl * assertDecl );
 
 	  private:
@@ -296,6 +297,6 @@
 	}
 
-	bool isStructOrUnion( Declaration *decl ) {
-		return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl );
+	bool shouldHoist( Declaration *decl ) {
+		return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl );
 	}
 
@@ -310,5 +311,5 @@
 		} // if
 		// Always remove the hoisted aggregate from the inner structure.
-		GuardAction( [aggregateDecl]() { filter( aggregateDecl->members, isStructOrUnion, false ); } );
+		GuardAction( [aggregateDecl]() { filter( aggregateDecl->members, shouldHoist, false ); } );
 	}
 
@@ -328,4 +329,10 @@
 		if ( inst->baseUnion ) {
 			declsToAddBefore.push_front( inst->baseUnion );
+		}
+	}
+
+	void HoistStruct::previsit( StaticAssertDecl * assertDecl ) {
+		if ( parentAggr ) {
+			declsToAddBefore.push_back( assertDecl );
 		}
 	}
@@ -630,4 +637,8 @@
 			forallFixer( pointer->base->forall, object );
 		} // if
+		// ensure that operator names only apply to functions or function pointers
+		if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) {
+			SemanticError( object->location, toCString( "operator ", object->name.c_str(), " is not a function or function pointer." )  );
+		}
 		object->fixUniqueId();
 	}
Index: src/SynTree/Declaration.cc
===================================================================
--- src/SynTree/Declaration.cc	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/SynTree/Declaration.cc	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -81,4 +81,27 @@
 
 
+StaticAssertDecl::StaticAssertDecl( Expression * condition, ConstantExpr * message ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), condition( condition ), message( message )  {
+}
+
+StaticAssertDecl::StaticAssertDecl( const StaticAssertDecl & other ) : Declaration( other ), condition( maybeClone( other.condition ) ), message( maybeClone( other.message ) )  {
+}
+
+StaticAssertDecl::~StaticAssertDecl() {
+	delete condition;
+	delete message;
+}
+
+void StaticAssertDecl::print( std::ostream &os, Indenter indent ) const {
+	os << "Static Assert with condition: ";
+	condition->print( os, indent+1 );
+	os << std::endl << indent << "and message: ";
+	message->print( os, indent+1 );
+os << std::endl;
+}
+
+void StaticAssertDecl::printShort( std::ostream &os, Indenter indent ) const {
+	print( os, indent );
+}
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/SynTree/Declaration.h	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -365,4 +365,20 @@
 };
 
+class StaticAssertDecl : public Declaration {
+public:
+	Expression * condition;
+	ConstantExpr * message;   // string literal
+
+	StaticAssertDecl( Expression * condition, ConstantExpr * message );
+	StaticAssertDecl( const StaticAssertDecl & other );
+	virtual ~StaticAssertDecl();
+
+	virtual StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual StaticAssertDecl * acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
+};
+
 std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data );
 
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/SynTree/Mutator.h	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -34,4 +34,5 @@
 	virtual Declaration * mutate( TypedefDecl * typeDecl ) = 0;
 	virtual AsmDecl * mutate( AsmDecl * asmDecl ) = 0;
+	virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) = 0;
 
 	virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) = 0;
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/SynTree/SynTree.h	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -38,4 +38,5 @@
 class TypedefDecl;
 class AsmDecl;
+class StaticAssertDecl;
 
 class Statement;
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/SynTree/Visitor.h	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -36,4 +36,5 @@
 	virtual void visit( TypedefDecl * typeDecl ) = 0;
 	virtual void visit( AsmDecl * asmDecl ) = 0;
+	virtual void visit( StaticAssertDecl * assertDecl ) = 0;
 
 	virtual void visit( CompoundStmt * compoundStmt ) = 0;
Index: src/tests/.expect/references.txt
===================================================================
--- src/tests/.expect/references.txt	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/tests/.expect/references.txt	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -4,4 +4,8 @@
 13 1 12
 14 14
+x = 6 ; x2 = 789
+x = 6 ; x2 = 999
+x = 12345 ; x2 = 999
+x = 22222 ; x2 = 999
 Default constructing a Y
 Copy constructing a Y
Index: src/tests/operators.c
===================================================================
--- src/tests/operators.c	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/tests/operators.c	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -27,6 +27,4 @@
 	a(b);
 	a + b;
-	struct accumulator ?+?;	// why not, eh?
-	a + b;
 }
 
Index: src/tests/references.c
===================================================================
--- src/tests/references.c	(revision 8ad653339f39e704e4be3cbd354de857c44a52f4)
+++ src/tests/references.c	(revision ca374456181d2f3ca0a61f3c111e0b915fa01059)
@@ -46,13 +46,9 @@
 
 int main() {
-	int x = 123456, *p1 = &x, **p2 = &p1, ***p3 = &p2,
+	int x = 123456, x2 = 789, *p1 = &x, **p2 = &p1, ***p3 = &p2,
 		&r1 = x,    &&r2 = r1,   &&&r3 = r2;
 	***p3 = 3;                          // change x
-	// ((int&)r3 = 3;                      // change x, ***r3
 	**p3 = &x;                          // change p1
-	// ((int*&)&r3) = &x;                  // change r1, (&*)**r3
 	*p3 = &p1;                          // change p2
-	// ((int**&)&&r3) = &p2;               // change r2, (&(&*)*)*r3
-	// ((int***&)&&&r3) = p3;              // change r3 to p3, (&(&(&*)*)*)r3
 	int y = 0, z = 11, & ar[3] = { x, y, z };    // initialize array of references
 	// &ar[1] = &z;                        // change reference array element
@@ -62,4 +58,6 @@
 	// sizeof( &ar[1] ) == sizeof( int *); // is true, i.e., the size of a reference
 
+	((int*&)&r3) = &x;                  // change r1, (&*)**r3
+	x = 3;
 	// test that basic reference properties are true - r1 should be an alias for x
 	printf("%d %d %d\n", x, r1, &x == &r1);
@@ -76,4 +74,16 @@
 	changeRef( r1 );
 	printf("%d %d\n", r1, x);
+
+	((int&)r3) = 6;                       // change x, ***r3
+	printf("x = %d ; x2 = %d\n", x, x2);  // check that x was changed
+	((int*&)&r3) = &x2;                   // change r1 to refer to x2, (&*)**r3
+	((int&)r3) = 999;                     // modify x2
+	printf("x = %d ; x2 = %d\n", x, x2);  // check that x2 was changed
+	((int**&)&&r3) = p2;                  // change r2, (&(&*)*)*r3
+	((int&)r3) = 12345;                   // modify x
+	printf("x = %d ; x2 = %d\n", x, x2);  // check that x was changed
+	((int***&)&&&r3) = p3;                // change r3 to p3, (&(&(&*)*)*)r3
+	((int&)r3) = 22222;                   // modify x
+	printf("x = %d ; x2 = %d\n", x, x2);  // check that x was changed
 
 	// test that reference members are not implicitly constructed/destructed/assigned
