Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision 5f08961d04c47678910366c75e15d9ab91808630)
+++ src/GenPoly/Lvalue.cc	(revision a3323db19a224d716f0e5bae4165484cef7febdb)
@@ -98,12 +98,17 @@
 		};
 
-		struct AddrRef final : public WithGuards {
+		struct AddrRef final : public WithGuards, public WithVisitorRef<AddrRef>, public WithShortCircuiting {
 			void premutate( AddressExpr * addrExpr );
 			Expression * postmutate( AddressExpr * addrExpr );
 			void premutate( Expression * expr );
+			void premutate( ApplicationExpr * appExpr );
+			void premutate( SingleInit * init );
+
+			void handleNonAddr( Expression * );
 
 			bool first = true;
 			bool current = false;
 			int refDepth = 0;
+			bool addCast = false;
 		};
 	} // namespace
@@ -208,4 +213,12 @@
 						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
+
+							// NOTE: previously, this condition fixed
+							//   void f(int *&);
+							//   int & x = ...;
+							//   f(&x);
+							// But now this is taken care of by a reference cast added by AddrRef. Need to find a new
+							// example or remove this branch.
+
 							PRINT(
 								std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl;
@@ -233,7 +246,10 @@
 
 		// idea: &&&E: get outer &, inner &
-		// at inner &, record depth D of reference type
+		// at inner &, record depth D of reference type of argument of &
 		// at outer &, add D derefs.
-		void AddrRef::premutate( Expression * ) {
+		void AddrRef::handleNonAddr( Expression * ) {
+			// non-address-of: reset status variables:
+			// * current expr is NOT the first address-of expr in an address-of chain
+			// * next seen address-of expr IS the first in the chain.
 			GuardValue( current );
 			GuardValue( first );
@@ -242,12 +258,18 @@
 		}
 
+		void AddrRef::premutate( Expression * expr ) {
+			handleNonAddr( expr );
+			GuardValue( addCast );
+			addCast = false;
+		}
+
 		void AddrRef::premutate( AddressExpr * ) {
 			GuardValue( current );
 			GuardValue( first );
-			current = first;
-			first = false;
-			if ( current ) {
+			current = first; // is this the first address-of in the chain?
+			first = false;   // from here out, no longer possible for next address-of to be first in chain
+			if ( current ) { // this is the outermost address-of in a chain
 				GuardValue( refDepth );
-				refDepth = 0;
+				refDepth = 0;  // set depth to 0 so that postmutate can find the innermost address-of easily
 			}
 		}
@@ -255,19 +277,46 @@
 		Expression * AddrRef::postmutate( AddressExpr * addrExpr ) {
 			if ( refDepth == 0 ) {
+				// this is the innermost address-of in a chain, record depth D
 				if ( ! isIntrinsicReference( addrExpr->arg ) ) {
 					// try to avoid ?[?]
+					// xxx - is this condition still necessary? intrinsicReferences should have a cast around them at this point, so I don't think this condition ever fires.
 					refDepth = addrExpr->arg->result->referenceDepth();
-				}
-			}
-			if ( current ) {
+				} else {
+					assertf( false, "AddrRef : address-of should not have intrinsic reference argument: %s", toCString( addrExpr->arg ) );
+				}
+			}
+			if ( current ) { // this is the outermost address-of in a chain
 				Expression * ret = addrExpr;
 				while ( refDepth ) {
+					// add one dereference for each
 					ret = mkDeref( ret );
 					refDepth--;
 				}
+
+				if ( addCast ) {
+					return new CastExpr( ret, addrExpr->result->clone() );
+				}
 				return ret;
 			}
 			return addrExpr;
 		}
+
+		void AddrRef::premutate( ApplicationExpr * appExpr ) {
+			visit_children = false;
+			GuardValue( addCast );
+			handleNonAddr( appExpr );
+			for ( Expression *& arg : appExpr->args ) {
+				// each argument with address-of requires a cast
+				addCast = true;
+				arg = arg->acceptMutator( *visitor );
+			}
+		}
+
+		void AddrRef::premutate( SingleInit * ) {
+			GuardValue( addCast );
+			// each initialization context with address-of requires a cast
+			addCast = true;
+		}
+
 
 		Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) {
