Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision f465f0efc6723994ba010946979c16ba519b8f04)
+++ src/SymTab/Indexer.cc	(revision dd226e352c29d5c532c8a9fc0ebd7042831afc2b)
@@ -26,4 +26,5 @@
 #include "Common/SemanticError.h"  // for SemanticError
 #include "Common/utility.h"        // for cloneAll
+#include "GenPoly/GenPoly.h"
 #include "InitTweak/InitTweak.h"   // for isConstructor, isCopyFunction, isC...
 #include "Mangler.h"               // for Mangler
@@ -377,8 +378,27 @@
 	}
 
+	bool isFunction( DeclarationWithType * decl ) {
+		return GenPoly::getFunctionType( decl->get_type() );
+	}
+
+	bool isObject( DeclarationWithType * decl ) {
+		return ! isFunction( decl );
+	}
+
+	bool isDefinition( DeclarationWithType * decl ) {
+		if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
+			// a function is a definition if it has a body
+			return func->statements;
+		} else {
+			// an object is a definition if it is not marked extern.
+			// both objects must be marked extern
+			return ! decl->get_storageClasses().is_extern;
+		}
+	}
+
 	bool addedIdConflicts( Indexer::IdData & existing, DeclarationWithType *added, BaseSyntaxNode * deleteStmt, Indexer::ConflictFunction handleConflicts ) {
 		// if we're giving the same name mangling to things of different types then there is something wrong
-		assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing.id ) )
-			|| (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing.id ) ) );
+		assert( (isObject( added ) && isObject( existing.id ) )
+			|| ( isFunction( added ) && isFunction( existing.id ) ) );
 
 		if ( LinkageSpec::isOverridable( existing.id->get_linkage() ) ) {
@@ -394,20 +414,8 @@
 			}
 
-			// typesCompatible doesn't really do the right thing here. When checking compatibility of function types,
-			// we should ignore outermost pointer qualifiers, except _Atomic?
-			FunctionDecl * newentry = dynamic_cast< FunctionDecl * >( added );
-			FunctionDecl * oldentry = dynamic_cast< FunctionDecl * >( existing.id );
-			if ( newentry && oldentry ) {
-				if ( newentry->get_statements() && oldentry->get_statements() ) {
+			if ( isDefinition( added ) && isDefinition( existing.id ) ) {
+				if ( isFunction( added ) ) {
 					return handleConflicts( existing, "duplicate function definition for " );
-				} // if
-			} else {
-				// two objects with the same mangled name defined in the same scope.
-				// both objects must be marked extern or both must be intrinsic for this to be okay
-				// xxx - perhaps it's actually if either is intrinsic then this is okay?
-				//       might also need to be same storage class?
-				ObjectDecl * newobj = dynamic_cast< ObjectDecl * >( added );
-				ObjectDecl * oldobj = dynamic_cast< ObjectDecl * >( existing.id );
-				if ( ! newobj->get_storageClasses().is_extern && ! oldobj->get_storageClasses().is_extern ) {
+				} else {
 					return handleConflicts( existing, "duplicate object definition for " );
 				} // if
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision f465f0efc6723994ba010946979c16ba519b8f04)
+++ src/SymTab/Mangler.cc	(revision dd226e352c29d5c532c8a9fc0ebd7042831afc2b)
@@ -179,5 +179,6 @@
 			void Mangler::postvisit( PointerType * pointerType ) {
 				printQualifiers( pointerType );
-				mangleName << "P";
+				// mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
+				if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << "P";
 				maybeAccept( pointerType->base, *visitor );
 			}
