Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision fbcde641e97f117504d1c8e0bee89efe2630a6e8)
+++ src/SymTab/Validate.cc	(revision fbd7ad6be2cf17535f03152e63720398a1ec288b)
@@ -208,4 +208,18 @@
 	};
 
+	class ArrayLength : public Visitor {
+	public:
+		/// for array types without an explicit length, compute the length and store it so that it
+		/// is known to the rest of the phases. For example,
+		///   int x[] = { 1, 2, 3 };
+		///   int y[][2] = { { 1, 2, 3 }, { 1, 2, 3 } };
+		/// here x and y are known at compile-time to have length 3, so change this into
+		///   int x[3] = { 1, 2, 3 };
+		///   int y[3][2] = { { 1, 2, 3 }, { 1, 2, 3 } };
+		static void computeLength( std::list< Declaration * > & translationUnit );
+
+		virtual void visit( ObjectDecl * objDecl );
+	};
+
 	class CompoundLiteral final : public GenPoly::DeclMutator {
 		Type::StorageClasses storageClasses;
@@ -235,4 +249,5 @@
 		acceptAll( translationUnit, pass3 );
 		VerifyCtorDtorAssign::verify( translationUnit );
+		ArrayLength::computeLength( translationUnit );
 	}
 
@@ -869,4 +884,18 @@
 		}
 	}
+
+	void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) {
+		ArrayLength len;
+		acceptAll( translationUnit, len );
+	}
+
+	void ArrayLength::visit( ObjectDecl * objDecl ) {
+		if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
+			if ( at->get_dimension() != nullptr ) return;
+			if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->get_init() ) ) {
+				at->set_dimension( new ConstantExpr( Constant::from_ulong( init->get_initializers().size() ) ) );
+			}
+		}
+	}
 } // namespace SymTab
 
