Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 02e5ab617410cc0bcf5ec7f06346d0a740096d7c)
+++ src/ResolvExpr/Unify.cc	(revision 1cbca6e153ee9b6e6d883a6d517fe9cb3d2873ad)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 12:27:10 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jun 26 14:57:05 2015
-// Update Count     : 7
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Sep 02 14:43:22 2015
+// Update Count     : 36
 //
 
@@ -28,5 +28,5 @@
 
 
-//#define DEBUG
+// #define DEBUG
 
 namespace ResolvExpr {
@@ -80,9 +80,15 @@
 	bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		TypeEnvironment newEnv;
-		OpenVarSet openVars;
+		OpenVarSet openVars, closedVars; // added closedVars
 		AssertionSet needAssertions, haveAssertions;
 		Type *newFirst = first->clone(), *newSecond = second->clone();
 		env.apply( newFirst );
 		env.apply( newSecond );
+
+		// do we need to do this? Seems like we do, types should be able to be compatible if they
+		// have free variables that can unify
+		findOpenVars( newFirst, openVars, closedVars, needAssertions, haveAssertions, false );
+		findOpenVars( newSecond, openVars, closedVars, needAssertions, haveAssertions, true );
+
 		bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 		delete newFirst;
@@ -425,7 +431,31 @@
 
 	void Unify::visit(ArrayType *arrayType) {
-		// XXX -- compare array dimension
 		ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
-		if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
+		// to unify, array types must both be VLA or both not VLA
+		// and must both have a dimension expression or not have a dimension
+		if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() 
+				&& ((arrayType->get_dimension() != 0 && otherArray->get_dimension() != 0)
+					|| (arrayType->get_dimension() == 0 && otherArray->get_dimension() == 0))) {
+
+			// not positive this is correct in all cases, but it's needed for typedefs
+			if ( arrayType->get_isVarLen() || otherArray->get_isVarLen() ) {
+				return;
+			}
+
+			if ( ! arrayType->get_isVarLen() && ! otherArray->get_isVarLen() &&
+				arrayType->get_dimension() != 0 && otherArray->get_dimension() != 0 ) {
+				ConstantExpr * ce1 = dynamic_cast< ConstantExpr * >( arrayType->get_dimension() );
+				ConstantExpr * ce2 = dynamic_cast< ConstantExpr * >( otherArray->get_dimension() );
+				assert(ce1 && ce2);
+
+				Constant * c1 = ce1->get_constant();
+				Constant * c2 = ce2->get_constant();
+
+				if ( c1->get_value() != c2->get_value() ) {
+					// does not unify if the dimension is different
+					return;
+				}
+			}
+
 			result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
 		} // if
@@ -435,4 +465,6 @@
 	bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
 		for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
+			// Type * commonType;
+			// if ( ! unifyInexact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) {
 			if ( ! unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
 				return false;
@@ -449,5 +481,5 @@
 		FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
 		if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
-  
+
 			if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
 	
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 02e5ab617410cc0bcf5ec7f06346d0a740096d7c)
+++ src/SymTab/Validate.cc	(revision 1cbca6e153ee9b6e6d883a6d517fe9cb3d2873ad)
@@ -54,4 +54,5 @@
 #include "MakeLibCfa.h"
 #include "TypeEquality.h"
+#include "ResolvExpr/typeops.h"
 
 #define debugPrint( x ) if ( doDebug ) { std::cout << x; }
@@ -851,5 +852,5 @@
 			Type * t1 = tyDecl->get_base();
 			Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
-			if ( ! typeEquals( t1, t2, true ) ) {
+			if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) {
 				throw SemanticError( "cannot redefine typedef: " + tyDecl->get_name() );
 			}
Index: src/SynTree/ObjectDecl.cc
===================================================================
--- src/SynTree/ObjectDecl.cc	(revision 02e5ab617410cc0bcf5ec7f06346d0a740096d7c)
+++ src/SynTree/ObjectDecl.cc	(revision 1cbca6e153ee9b6e6d883a6d517fe9cb3d2873ad)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Jul 13 18:08:27 2015
-// Update Count     : 16
+// Last Modified By : Rob Schluntz
+// Last Modified On : Tue Sep 29 14:13:01 2015
+// Update Count     : 18
 //
 
@@ -52,14 +52,14 @@
 		get_type()->print( os, indent );
 	} else {
-		os << "untyped entity ";
+		os << " untyped entity ";
 	} // if
 
 	if ( init ) {
-		os << "with initializer ";
+		os << " with initializer ";
 		init->print( os, indent );
 	} // if
 
 	if ( bitfieldWidth ) {
-		os << "with bitfield width ";
+		os << " with bitfield width ";
 		bitfieldWidth->print( os );
 	} // if
