Index: src/SynTree/Attribute.cc
===================================================================
--- src/SynTree/Attribute.cc	(revision 09928490678e146befd5d185f92f38d99e9431b3)
+++ src/SynTree/Attribute.cc	(revision 490ff5c3cdf33976fd18d953a739387a1031d3c6)
@@ -15,4 +15,5 @@
 
 #include <ostream>           // for operator<<, ostream, basic_ostream, endl
+#include <set>
 
 #include "Attribute.h"
@@ -21,22 +22,43 @@
 
 Attribute::Attribute( const Attribute &other ) : name( other.name ) {
-  cloneAll( other.parameters, parameters );
+	cloneAll( other.parameters, parameters );
 }
 
 Attribute::~Attribute() {
-  deleteAll( parameters );
+	deleteAll( parameters );
+}
+
+bool Attribute::isValidOnFuncParam() const {
+	// attributes such as aligned, cleanup, etc. produce GCC errors when they appear
+	// on function parameters. Maintain here a whitelist of attribute names that are
+	// allowed to appear on parameters.
+	static std::set< std::string > valid = {
+		"noreturn", "unused"
+	};
+	return valid.count( normalizedName() );
+}
+
+std::string Attribute::normalizedName() const {
+	// trim beginning/ending _, convert to lowercase
+	auto begin = name.find_first_not_of('_');
+	auto end = name.find_last_not_of('_');
+	if (begin == std::string::npos || end == std::string::npos) return "";
+	std::string ret;
+	ret.reserve( end-begin+1 );
+	std::transform( &name[begin], &name[end+1], back_inserter( ret ), tolower );
+	return ret;
 }
 
 void Attribute::print( std::ostream &os, Indenter indent ) const {
-  using std::endl;
-  using std::string;
+	using std::endl;
+	using std::string;
 
-  if ( ! empty() ) {
-    os << "Attribute with name: " << name;
-    if ( ! parameters.empty() ) {
-      os << " with parameters: " << endl;
-      printAll( parameters, os, indent+1 );
-    }
-  }
+	if ( ! empty() ) {
+		os << "Attribute with name: " << name;
+		if ( ! parameters.empty() ) {
+			os << " with parameters: " << endl;
+			printAll( parameters, os, indent+1 );
+		}
+	}
 }
 
Index: src/SynTree/Attribute.h
===================================================================
--- src/SynTree/Attribute.h	(revision 09928490678e146befd5d185f92f38d99e9431b3)
+++ src/SynTree/Attribute.h	(revision 490ff5c3cdf33976fd18d953a739387a1031d3c6)
@@ -43,4 +43,9 @@
 	bool empty() const { return name == ""; }
 
+	std::string normalizedName() const;
+
+	/// true if this attribute is allowed to appear attached to a function parameter
+	bool isValidOnFuncParam() const;
+
 	Attribute * clone() const override { return new Attribute( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
