Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision e5d4e5c501242024833e1ed47aa37fccc9f78b23)
+++ src/GenPoly/Box.cc	(revision 560074792e28fca668389bd92e2b25a41de50943)
@@ -163,4 +163,6 @@
 			void premutate( DeclStmt *declStmt );
 			Expression *postmutate( MemberExpr *memberExpr );
+			void premutate( AddressExpr *addrExpr );
+			Expression *postmutate( AddressExpr *addrExpr );
 			Expression *postmutate( SizeofExpr *sizeofExpr );
 			Expression *postmutate( AlignofExpr *alignofExpr );
@@ -193,4 +195,5 @@
 			ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
 			UniqueName bufNamer;                           ///< Namer for VLA buffers
+			Expression * addrMember = nullptr;             ///< AddressExpr argument is MemberExpr?
 		};
 
@@ -1174,5 +1177,5 @@
 			if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
 				if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
-					if ( name->get_name() == "*?" ) {
+					if ( name->name == "*?" ) {
 						Expression *ret = expr->args.front();
 						expr->args.clear();
@@ -1187,14 +1190,14 @@
 		void Pass1::premutate( AddressExpr * ) { visit_children = false; }
 		Expression * Pass1::postmutate( AddressExpr * addrExpr ) {
-			assert( addrExpr->get_arg()->result && ! addrExpr->get_arg()->get_result()->isVoid() );
+			assert( addrExpr->arg->result && ! addrExpr->arg->result->isVoid() );
 
 			bool needs = false;
-			if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
-				if ( expr->result && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
-					if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
-						if ( name->get_name() == "*?" ) {
-							if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
-								assert( appExpr->get_function()->result );
-								FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
+			if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) {
+				if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
+					if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
+						if ( name->name == "*?" ) {
+							if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) {
+								assert( appExpr->function->result );
+								FunctionType *function = getFunctionType( appExpr->function->result );
 								assert( function );
 								needs = needsAdapter( function, scopeTyVars );
@@ -1206,12 +1209,12 @@
 			// isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
 			// out of the if condition.
-			addrExpr->arg = addrExpr->get_arg()->acceptMutator( *visitor );
+			addrExpr->arg = addrExpr->arg->acceptMutator( *visitor );
 			// ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment
-			bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
+			bool polytype = isPolyType( addrExpr->arg->result, scopeTyVars, env );
 			if ( polytype || needs ) {
-				Expression *ret = addrExpr->get_arg();
-				delete ret->get_result();
-				ret->set_result( addrExpr->get_result()->clone() );
-				addrExpr->set_arg( 0 );
+				Expression *ret = addrExpr->arg;
+				delete ret->result;
+				ret->result = addrExpr->result->clone();
+				addrExpr->arg = nullptr;
 				delete addrExpr;
 				return ret;
@@ -1250,5 +1253,5 @@
 
 		void Pass2::addAdapters( FunctionType *functionType ) {
-			std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
+			std::list< DeclarationWithType *> &paramList = functionType->parameters;
 			std::list< FunctionType *> functions;
 			for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
@@ -1271,22 +1274,22 @@
 
 		DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) {
-			FunctionType * ftype = functionDecl->get_functionType();
-			if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) {
-				if ( ! isPrefix( functionDecl->get_name(), "_thunk" ) && ! isPrefix( functionDecl->get_name(), "_adapter" ) ) { // xxx - remove check for prefix once thunks properly use ctor/dtors
-					assert( ftype->get_returnVals().size() == 1 );
-					DeclarationWithType * retval = ftype->get_returnVals().front();
-					if ( retval->get_name() == "" ) {
-						retval->set_name( "_retval" );
+			FunctionType * ftype = functionDecl->type;
+			if ( ! ftype->returnVals.empty() && functionDecl->statements ) {
+				if ( ! isPrefix( functionDecl->name, "_thunk" ) && ! isPrefix( functionDecl->name, "_adapter" ) ) { // xxx - remove check for prefix once thunks properly use ctor/dtors
+					assert( ftype->returnVals.size() == 1 );
+					DeclarationWithType * retval = ftype->returnVals.front();
+					if ( retval->name == "" ) {
+						retval->name = "_retval";
 					}
-					functionDecl->get_statements()->get_kids().push_front( new DeclStmt( retval ) );
+					functionDecl->statements->kids.push_front( new DeclStmt( retval ) );
 					DeclarationWithType * newRet = retval->clone(); // for ownership purposes
-					ftype->get_returnVals().front() = newRet;
+					ftype->returnVals.front() = newRet;
 				}
 			}
 			// errors should have been caught by this point, remove initializers from parameters to allow correct codegen of default arguments
-			for ( Declaration * param : functionDecl->get_functionType()->get_parameters() ) {
+			for ( Declaration * param : functionDecl->type->parameters ) {
 				if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( param ) ) {
-					delete obj->get_init();
-					obj->set_init( nullptr );
+					delete obj->init;
+					obj->init = nullptr;
 				}
 			}
@@ -1584,5 +1587,13 @@
 			assert( newMemberExpr );
 
-			Type *memberType = memberExpr->member->get_type();
+			// Must apply the generic substitution to the member type to handle cases where the member is a generic parameter substituted by a known concrete type, e.g.
+			//   forall(otype T) struct Box { T x; }
+			//   forall(otype T) f() {
+			//     Box(T *) b; b.x;
+			//   }
+			// TODO: memberExpr->result should be exactly memberExpr->member->get_type() after substitution, so it doesn't seem like it should be necessary to apply the substitution manually. For some reason this is not currently the case. This requires more investigation.
+			Type *memberType = memberExpr->member->get_type()->clone();
+			TypeSubstitution sub = objectType->genericSubstitution();
+			sub.apply( memberType );
 			if ( ! isPolyType( memberType, scopeTyVars ) ) {
 				// Not all members of a polymorphic type are themselves of polymorphic type; in this case the member expression should be wrapped and dereferenced to form an lvalue
@@ -1592,6 +1603,31 @@
 			}
 
+			delete memberType;
 			delete memberExpr;
 			return newMemberExpr;
+		}
+
+		void PolyGenericCalculator::premutate( AddressExpr * addrExpr ) {
+			GuardValue( addrMember );
+			// is the argument a MemberExpr before mutating?
+			addrMember = dynamic_cast< MemberExpr * >( addrExpr->arg );
+		}
+
+		Expression * PolyGenericCalculator::postmutate( AddressExpr * addrExpr ) {
+			if ( addrMember && addrMember != addrExpr->arg ) {
+				// arg was a MemberExpr and has been mutated
+				if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( addrExpr->arg ) ) {
+					if ( InitTweak::getFunctionName( untyped ) == "?+?" ) {
+						// MemberExpr was converted to pointer+offset, and it is not valid C to take the address of an addition, so strip the address-of
+						// TODO: should  addrExpr->arg->result be changed to addrExpr->result?
+						Expression * ret = addrExpr->arg;
+						addrExpr->arg = nullptr;
+						std::swap( addrExpr->env, ret->env );
+						delete addrExpr;
+						return ret;
+					}
+				}
+			}
+			return addrExpr;
 		}
 
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision e5d4e5c501242024833e1ed47aa37fccc9f78b23)
+++ src/SynTree/Expression.cc	(revision 560074792e28fca668389bd92e2b25a41de50943)
@@ -345,25 +345,11 @@
 }
 
-namespace {
-	TypeSubstitution makeSub( Type * 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->parameters.begin() );
-		} else if ( UnionInstType * aggInst = dynamic_cast< UnionInstType * >( t ) ) {
-			return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->parameters.begin() );
-		} else {
-			assertf( false, "makeSub expects struct or union type for aggregate, but got: %s", toString( t ).c_str() );
-		}
-	}
-}
-
-
 MemberExpr::MemberExpr( DeclarationWithType *member, Expression *aggregate ) :
 		Expression(), member(member), aggregate(aggregate) {
 	assert( member );
 	assert( aggregate );
-
-	TypeSubstitution sub( makeSub( aggregate->get_result() ) );
+	assert( aggregate->result );
+
+	TypeSubstitution sub = aggregate->result->genericSubstitution();
 	Type * res = member->get_type()->clone();
 	sub.apply( res );
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision e5d4e5c501242024833e1ed47aa37fccc9f78b23)
+++ src/SynTree/ReferenceToType.cc	(revision 560074792e28fca668389bd92e2b25a41de50943)
@@ -14,13 +14,14 @@
 //
 
-#include <cassert>           // for assert
-#include <list>              // for list, _List_const_iterator, list<>::cons...
-#include <ostream>           // for operator<<, basic_ostream, ostream, endl
-#include <string>            // for string, operator<<, char_traits, operator==
-
-#include "Common/utility.h"  // for printAll, cloneAll, deleteAll
-#include "Declaration.h"     // for StructDecl, UnionDecl, EnumDecl, Declara...
-#include "Expression.h"      // for Expression
-#include "Type.h"            // for TypeInstType, StructInstType, UnionInstType
+#include <cassert>            // for assert
+#include <list>               // for list, _List_const_iterator, list<>::cons...
+#include <ostream>            // for operator<<, basic_ostream, ostream, endl
+#include <string>             // for string, operator<<, char_traits, operator==
+
+#include "Common/utility.h"   // for printAll, cloneAll, deleteAll
+#include "Declaration.h"      // for StructDecl, UnionDecl, EnumDecl, Declara...
+#include "Expression.h"       // for Expression
+#include "Type.h"             // for TypeInstType, StructInstType, UnionInstType
+#include "TypeSubstitution.h" // for TypeSubstitution
 
 class Attribute;
@@ -63,4 +64,9 @@
 std::string StructInstType::typeString() const { return "struct"; }
 
+const std::list<TypeDecl*>* StructInstType::get_baseParameters() const {
+	if ( ! baseStruct ) return nullptr;
+	return &baseStruct->get_parameters();
+}
+
 std::list<TypeDecl*>* StructInstType::get_baseParameters() {
 	if ( ! baseStruct ) return nullptr;
@@ -71,4 +77,8 @@
 
 AggregateDecl * StructInstType::getAggr() { return baseStruct; }
+
+TypeSubstitution StructInstType::genericSubstitution() const {
+	return TypeSubstitution( get_baseParameters()->begin(), get_baseParameters()->end(), parameters.begin() );
+}
 
 void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
@@ -102,7 +112,16 @@
 }
 
+const std::list< TypeDecl * > * UnionInstType::get_baseParameters() const {
+	if ( ! baseUnion ) return nullptr;
+	return &baseUnion->get_parameters();
+}
+
 bool UnionInstType::isComplete() const { return baseUnion ? baseUnion->has_body() : false; }
 
 AggregateDecl * UnionInstType::getAggr() { return baseUnion; }
+
+TypeSubstitution UnionInstType::genericSubstitution() const {
+	return TypeSubstitution( get_baseParameters()->begin(), get_baseParameters()->end(), parameters.begin() );
+}
 
 void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
Index: src/SynTree/ReferenceType.cc
===================================================================
--- src/SynTree/ReferenceType.cc	(revision e5d4e5c501242024833e1ed47aa37fccc9f78b23)
+++ src/SynTree/ReferenceType.cc	(revision 560074792e28fca668389bd92e2b25a41de50943)
@@ -16,4 +16,5 @@
 #include "Type.h"
 #include "Expression.h"
+#include "TypeSubstitution.h"
 #include "Common/utility.h"
 
@@ -35,4 +36,6 @@
 }
 
+TypeSubstitution ReferenceType::genericSubstitution() const { return base->genericSubstitution(); }
+
 void ReferenceType::print( std::ostream &os, Indenter indent ) const {
 	Type::print( os, indent );
Index: src/SynTree/Type.cc
===================================================================
--- src/SynTree/Type.cc	(revision e5d4e5c501242024833e1ed47aa37fccc9f78b23)
+++ src/SynTree/Type.cc	(revision 560074792e28fca668389bd92e2b25a41de50943)
@@ -15,9 +15,10 @@
 #include "Type.h"
 
-#include "Attribute.h"               // for Attribute
-#include "Common/utility.h"          // for cloneAll, deleteAll, printAll
-#include "InitTweak/InitTweak.h"     // for getPointerBase
-#include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
-#include "SynTree/Declaration.h"     // for TypeDecl
+#include "Attribute.h"                // for Attribute
+#include "Common/utility.h"           // for cloneAll, deleteAll, printAll
+#include "InitTweak/InitTweak.h"      // for getPointerBase
+#include "SynTree/BaseSyntaxNode.h"   // for BaseSyntaxNode
+#include "SynTree/Declaration.h"      // for TypeDecl
+#include "SynTree/TypeSubstitution.h" // for TypeSubstitution
 
 using namespace std;
@@ -81,4 +82,6 @@
 int Type::referenceDepth() const { return 0; }
 
+TypeSubstitution Type::genericSubstitution() const { assertf( false, "Non-aggregate type: %s", toCString( this ) ); }
+
 void Type::print( std::ostream &os, Indenter indent ) const {
 	if ( ! forall.empty() ) {
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision e5d4e5c501242024833e1ed47aa37fccc9f78b23)
+++ src/SynTree/Type.h	(revision 560074792e28fca668389bd92e2b25a41de50943)
@@ -178,5 +178,7 @@
 	virtual bool isComplete() const { return true; }
 
-	virtual AggregateDecl * getAggr() {	assertf( false, "Non-aggregate type: %s", toString( this ).c_str() ); }
+	virtual AggregateDecl * getAggr() { assertf( false, "Non-aggregate type: %s", toCString( this ) ); }
+
+	virtual TypeSubstitution genericSubstitution() const;
 
 	virtual Type *clone() const = 0;
@@ -329,4 +331,6 @@
 	virtual unsigned size() const override { return base->size(); }
 
+	virtual TypeSubstitution genericSubstitution() const override;
+
 	virtual ReferenceType *clone() const override { return new ReferenceType( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
@@ -406,8 +410,11 @@
 	/// Accesses generic parameters of base struct (NULL if none such)
 	std::list<TypeDecl*> * get_baseParameters();
+	const std::list<TypeDecl*> * get_baseParameters() const;
 
 	virtual bool isComplete() const override;
 
 	virtual AggregateDecl * getAggr() override;
+
+	virtual TypeSubstitution genericSubstitution() const override;
 
 	/// Looks up the members of this struct named "name" and places them into "foundDecls".
@@ -439,9 +446,12 @@
 
 	/// Accesses generic parameters of base union (NULL if none such)
-	std::list< TypeDecl * > * get_baseParameters();
+	std::list<TypeDecl*> * get_baseParameters();
+	const std::list<TypeDecl*> * get_baseParameters() const;
 
 	virtual bool isComplete() const override;
 
 	virtual AggregateDecl * getAggr() override;
+
+	virtual TypeSubstitution genericSubstitution() const override;
 
 	/// looks up the members of this union named "name" and places them into "foundDecls"
Index: src/tests/.expect/literals.x86.txt
===================================================================
--- src/tests/.expect/literals.x86.txt	(revision e5d4e5c501242024833e1ed47aa37fccc9f78b23)
+++ src/tests/.expect/literals.x86.txt	(revision 560074792e28fca668389bd92e2b25a41de50943)
@@ -522,4 +522,28 @@
 signed int __main__Fi___1(){
     __attribute__ ((unused)) signed int ___retval_main__i_1;
+    ((void)0b01101011);
+    ((void)0b01101011u);
+    ((void)0b01101011l);
+    ((void)0b01101011ll);
+    ((void)0b01101011ul);
+    ((void)0b01101011lu);
+    ((void)0b01101011ull);
+    ((void)0b01101011llu);
+    ((void)(+0b01101011));
+    ((void)(+0b01101011u));
+    ((void)(+0b01101011l));
+    ((void)(+0b01101011ll));
+    ((void)(+0b01101011ul));
+    ((void)(+0b01101011lu));
+    ((void)(+0b01101011ull));
+    ((void)(+0b01101011llu));
+    ((void)(-0b01101011));
+    ((void)(-0b01101011u));
+    ((void)(-0b01101011l));
+    ((void)(-0b01101011ll));
+    ((void)(-0b01101011ul));
+    ((void)(-0b01101011lu));
+    ((void)(-0b01101011ull));
+    ((void)(-0b01101011llu));
     ((void)01234567);
     ((void)01234567u);
@@ -1017,4 +1041,34 @@
     ((void)(-0X0123456789.0123456789P-09F));
     ((void)(-0X0123456789.0123456789P-09L));
+    ((void)((signed char )0b01101011));
+    ((void)((signed short int )0b01101011));
+    ((void)((signed int )0b01101011));
+    ((void)((signed long long int )0b01101011));
+    ((void)((__int128 )0b01101011));
+    ((void)((unsigned char )0b01101011u));
+    ((void)((signed short int )0b01101011u));
+    ((void)((unsigned int )0b01101011u));
+    ((void)((signed long long int )0b01101011u));
+    ((void)((__int128 )0b01101011u));
+    ((void)(+((signed int )((signed char )0b01101011))));
+    ((void)(+((signed int )((signed short int )0b01101011))));
+    ((void)(+((signed int )0b01101011)));
+    ((void)(+((signed long long int )0b01101011)));
+    ((void)(+((float )((__int128 )0b01101011))));
+    ((void)(+((signed int )((unsigned char )0b01101011u))));
+    ((void)(+((signed int )((signed short int )0b01101011u))));
+    ((void)(+((unsigned int )0b01101011u)));
+    ((void)(+((signed long long int )0b01101011u)));
+    ((void)(+((float )((__int128 )0b01101011u))));
+    ((void)(-((signed int )((signed char )0b01101011))));
+    ((void)(-((signed int )((signed short int )0b01101011))));
+    ((void)(-((signed int )0b01101011)));
+    ((void)(-((signed long long int )0b01101011)));
+    ((void)(-((float )((__int128 )0b01101011))));
+    ((void)(-((signed int )((unsigned char )0b01101011u))));
+    ((void)(-((signed int )((signed short int )0b01101011u))));
+    ((void)(-((unsigned int )0b01101011u)));
+    ((void)(-((signed long long int )0b01101011u)));
+    ((void)(-((float )((__int128 )0b01101011u))));
     ((void)((signed char )01234567));
     ((void)((signed short int )01234567));
