Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision a7caf3d39000047777d818c855ecc4954932e20b)
+++ src/GenPoly/Box.cc	(revision 1f37045134019dcc85ce9bbfe573c87275cfb714)
@@ -855,4 +855,13 @@
 			DeclarationWithType *adapteeDecl = adapterType->get_parameters().front();
 			adapteeDecl->set_name( "_adaptee" );
+			// do not carry over attributes to real type parameters/return values
+			for ( DeclarationWithType * dwt : realType->parameters ) {
+				deleteAll( dwt->get_type()->attributes );
+				dwt->get_type()->attributes.clear();
+			}
+			for ( DeclarationWithType * dwt : realType->returnVals ) {
+				deleteAll( dwt->get_type()->attributes );
+				dwt->get_type()->attributes.clear();
+			}
 			ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) );
 			Statement *bodyStmt;
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision a7caf3d39000047777d818c855ecc4954932e20b)
+++ src/Parser/TypeData.cc	(revision 1f37045134019dcc85ce9bbfe573c87275cfb714)
@@ -792,5 +792,5 @@
 
 
-NamedTypeDecl * buildSymbolic( const TypeData * td, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) {
+NamedTypeDecl * buildSymbolic( const TypeData * td, std::list< Attribute * > attributes, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) {
 	assert( td->kind == TypeData::Symbolic );
 	NamedTypeDecl * ret;
@@ -803,4 +803,5 @@
 	buildList( td->symbolic.params, ret->get_parameters() );
 	buildList( td->symbolic.assertions, ret->get_assertions() );
+	ret->base->attributes.splice( ret->base->attributes.end(), attributes );
 	return ret;
 } // buildSymbolic
@@ -866,5 +867,5 @@
 		return buildEnum( td, attributes, linkage );
 	} else if ( td->kind == TypeData::Symbolic ) {
-		return buildSymbolic( td, name, scs, linkage );
+		return buildSymbolic( td, attributes, name, scs, linkage );
 	} else {
 		return (new ObjectDecl( name, scs, linkage, bitfieldWidth, typebuild( td ), init, attributes ))->set_asmName( asmName );
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision a7caf3d39000047777d818c855ecc4954932e20b)
+++ src/SymTab/Autogen.cc	(revision 1f37045134019dcc85ce9bbfe573c87275cfb714)
@@ -372,5 +372,10 @@
 				continue;
 			}
-			memCtorType->parameters.push_back( new ObjectDecl( field->name, Type::StorageClasses(), LinkageSpec::Cforall, 0, field->get_type()->clone(), 0 ) );
+			// do not carry over field's attributes to parameter type
+			Type * paramType = field->get_type()->clone();
+			deleteAll( paramType->attributes );
+			paramType->attributes.clear();
+			// add a parameter corresponding to this field
+			memCtorType->parameters.push_back( new ObjectDecl( field->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType, nullptr ) );
 			FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting );
 			makeFieldCtorBody( aggregateDecl->members.begin(), aggregateDecl->members.end(), ctor );
@@ -503,5 +508,10 @@
 				break;
 			}
-			memCtorType->parameters.push_back( new ObjectDecl( field->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, field->get_type()->clone(), nullptr ) );
+			// do not carry over field's attributes to parameter type
+			Type * paramType = field->get_type()->clone();
+			deleteAll( paramType->attributes );
+			paramType->attributes.clear();
+			// add a parameter corresponding to this field
+			memCtorType->parameters.push_back( new ObjectDecl( field->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType, nullptr ) );
 			FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting );
 			ObjectDecl * srcParam = strict_dynamic_cast<ObjectDecl *>( ctor->type->parameters.back() );
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision a7caf3d39000047777d818c855ecc4954932e20b)
+++ src/SymTab/Validate.cc	(revision 1f37045134019dcc85ce9bbfe573c87275cfb714)
@@ -201,4 +201,6 @@
 		Declaration * postmutate( TraitDecl * contextDecl );
 
+		void premutate( FunctionType * ftype );
+
 	  private:
 		template<typename AggDecl>
@@ -214,4 +216,5 @@
 		TypeDeclMap typedeclNames;
 		int scopeLevel;
+		bool inFunctionType = false;
 	};
 
@@ -725,4 +728,11 @@
 			Type *ret = def->second.first->base->clone();
 			ret->get_qualifiers() |= typeInst->get_qualifiers();
+			// attributes are not carried over from typedef to function parameters/return values
+			if ( ! inFunctionType ) {
+				ret->attributes.splice( ret->attributes.end(), typeInst->attributes );
+			} else {
+				deleteAll( ret->attributes );
+				ret->attributes.clear();
+			}
 			// place instance parameters on the typedef'd type
 			if ( ! typeInst->parameters.empty() ) {
@@ -901,4 +911,9 @@
 	Declaration *EliminateTypedef::postmutate( TraitDecl * traitDecl ) {
 		return handleAggregate( traitDecl );
+	}
+
+	void EliminateTypedef::premutate( FunctionType * ) {
+		GuardValue( inFunctionType );
+		inFunctionType = true;
 	}
 
Index: src/tests/polymorphism.c
===================================================================
--- src/tests/polymorphism.c	(revision a7caf3d39000047777d818c855ecc4954932e20b)
+++ src/tests/polymorphism.c	(revision 1f37045134019dcc85ce9bbfe573c87275cfb714)
@@ -89,6 +89,8 @@
 		// ensure that the size of aggregates with polymorphic members
 		// matches the size of the aggregates in a monomorphic context
-		assertf( struct_size(x, y) == sizeof(S), "struct size differs in polymorphic context." );
-		assertf( union_size(x, y) == sizeof(U), "union size differs in polymorphic context." );
+		size_t ssz = struct_size(x, y);
+		size_t usz = union_size(x, y);
+		assertf( ssz == sizeof(S), "struct size differs in polymorphic context: %zd / %zd", ssz, sizeof(S));
+		assertf( usz == sizeof(U), "union size differs in polymorphic context: %zd / %zd", usz, sizeof(U));
 
 		y_type ?=?(y_type & this, zero_t) {
