Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 2a4b0884c14643e09650daaeb3a6667b5bff6b48)
+++ src/SymTab/Validate.cc	(revision d63eeb0d6eeb995b4c8c414f1d4989b0189ef8ca)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 21:50:04 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jan 27 22:03:12 2016
-// Update Count     : 225
+// Last Modified By : Rob Schluntz
+// Last Modified On : Tue Feb 09 13:21:56 2016
+// Update Count     : 270
 //
 
@@ -202,4 +202,17 @@
 	};
 
+	class VerifyCtorDtor : public Visitor {
+	public:
+		/// ensure that constructors and destructors have at least one
+		/// parameter, the first of which must be a pointer, and no
+		/// return values.
+		static void verify( std::list< Declaration * > &translationUnit );
+
+		// VerifyCtorDtor() {}
+
+		virtual void visit( FunctionDecl *funcDecl );
+	private:
+	};
+
 	void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
 		Pass1 pass1;
@@ -213,4 +226,5 @@
 		AutogenerateRoutines::autogenerateRoutines( translationUnit );
 		acceptAll( translationUnit, pass3 );
+		VerifyCtorDtor::verify( translationUnit );
 	}
 
@@ -745,5 +759,5 @@
 		makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
 		if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
-		
+
 		if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
 
@@ -1042,4 +1056,36 @@
 	}
 
+	void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) {
+		VerifyCtorDtor verifier;
+		acceptAll( translationUnit, verifier );
+	}
+
+	void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) {
+		FunctionType * funcType = funcDecl->get_functionType();
+		std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
+		std::list< DeclarationWithType * > &params = funcType->get_parameters();
+
+		if ( funcDecl->get_name() == "?{}" || funcDecl->get_name() == "^?{}" ) {
+			if ( params.size() == 0 ) {
+				throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl );
+			}
+			if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) {
+				throw SemanticError( "First parameter of a constructor or destructor must be a pointer ", funcDecl );
+			}
+			if ( returnVals.size() != 0 ) {
+				throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
+			}
+		}
+
+		Visitor::visit( funcDecl );
+		// original idea: modify signature of ctor/dtors and insert appropriate return statements
+		// to cause desired behaviour
+		// new idea: add comma exprs to every ctor call to produce first parameter.
+		// this requires some memoization of the first parameter, because it can be a
+		// complicated expression with side effects (see: malloc). idea: add temporary variable
+		// that is assigned address of constructed object in ctor argument position and
+		// return the temporary. It should also be done after all implicit ctors are
+		// added, so not in this pass!
+	}
 } // namespace SymTab
 
