Index: src/Validate/Autogen.cpp
===================================================================
--- src/Validate/Autogen.cpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/Validate/Autogen.cpp	(revision 5ecaeca582db8a0038f47d9ffc0c88db206dfc19)
@@ -440,5 +440,7 @@
 
 		auto * paramType = ast::deepCopy( member->get_type() );
-		paramType->attributes.clear();
+		erase_if( paramType->attributes, []( ast::Attribute const * attr ){
+			return !attr->isValidOnFuncParam();
+		} );
 		ast::ObjectDecl * param = new ast::ObjectDecl(
 			getLocation(), member->name, paramType );
Index: src/Validate/ReplaceTypedef.cpp
===================================================================
--- src/Validate/ReplaceTypedef.cpp	(revision 8b4faf639e449fe289d559f0202fd6e97f96d2d3)
+++ src/Validate/ReplaceTypedef.cpp	(revision 5ecaeca582db8a0038f47d9ffc0c88db206dfc19)
@@ -25,16 +25,4 @@
 
 namespace {
-
-bool isNonParameterAttribute( ast::Attribute const * attr ) {
-	static const std::vector<std::string> bad_names = {
-		"aligned", "__aligned__",
-	};
-	for ( auto name : bad_names ) {
-		if ( name == attr->name ) {
-			return true;
-		}
-	}
-	return false;
-}
 
 struct ReplaceTypedefCore final :
@@ -101,5 +89,7 @@
 		// by typedef. GCC appears to do the same thing.
 		if ( isAtFunctionTop ) {
-			erase_if( ret->attributes, isNonParameterAttribute );
+			erase_if( ret->attributes, []( ast::Attribute const * attr ){
+				return !attr->isValidOnFuncParam();
+			} );
 		}
 		for ( const auto & attribute : type->attributes ) {
