Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 4563a956eb56d3c7135208399eafd37c72ea72d3)
+++ src/InitTweak/InitTweak.cc	(revision d1969a607787c81d78565de2d2aaa145be1680e2)
@@ -358,5 +358,5 @@
 		template<typename CallExpr>
 		Expression *& callArg( CallExpr * callExpr, unsigned int pos ) {
-			if ( pos >= callExpr->get_args().size() ) assert( false && "asking for argument that doesn't exist. Return NULL/throw exception?" );
+			if ( pos >= callExpr->get_args().size() ) assertf( false, "asking for argument that doesn't exist. Return NULL/throw exception?" );
 			for ( Expression *& arg : callExpr->get_args() ) {
 				if ( pos == 0 ) return arg;
@@ -373,5 +373,5 @@
 			return callArg( untypedExpr, pos );
 		} else {
-			assert( false && "Unexpected expression type passed to getCallArg" );
+			assertf( false, "Unexpected expression type passed to getCallArg" );
 		}
 	}
@@ -388,5 +388,5 @@
 				return memberExpr->get_member()->get_name();
 			} else {
-				assert( false && "Unexpected expression type being called as a function in call expression" );
+				assertf( false, "Unexpected expression type being called as a function in call expression" );
 			}
 		}
@@ -400,5 +400,5 @@
 		} else {
 			std::cerr << expr << std::endl;
-			assert( false && "Unexpected expression type passed to getFunctionName" );
+			assertf( false, "Unexpected expression type passed to getFunctionName" );
 		}
 	}
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 4563a956eb56d3c7135208399eafd37c72ea72d3)
+++ src/SymTab/Validate.cc	(revision d1969a607787c81d78565de2d2aaa145be1680e2)
@@ -60,4 +60,5 @@
 #include "ResolvExpr/typeops.h"
 #include <algorithm>
+#include "InitTweak/InitTweak.h"
 
 #define debugPrint( x ) if ( doDebug ) { std::cout << x; }
@@ -171,8 +172,8 @@
 	};
 
-	class VerifyCtorDtor : public Visitor {
+	class VerifyCtorDtorAssign : public Visitor {
 	public:
-		/// ensure that constructors and destructors have at least one
-		/// parameter, the first of which must be a pointer, and no
+		/// ensure that constructors, destructors, and assignment have at least one
+		/// parameter, the first of which must be a pointer, and that ctor/dtors have no
 		/// return values.
 		static void verify( std::list< Declaration * > &translationUnit );
@@ -202,5 +203,5 @@
 		compoundliteral.mutateDeclarationList( translationUnit );
 		acceptAll( translationUnit, pass3 );
-		VerifyCtorDtor::verify( translationUnit );
+		VerifyCtorDtorAssign::verify( translationUnit );
 	}
 
@@ -687,22 +688,22 @@
 	}
 
-	void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) {
-		VerifyCtorDtor verifier;
+	void VerifyCtorDtorAssign::verify( std::list< Declaration * > & translationUnit ) {
+		VerifyCtorDtorAssign verifier;
 		acceptAll( translationUnit, verifier );
 	}
 
-	void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) {
+	void VerifyCtorDtorAssign::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 ( InitTweak::isCtorDtorAssign( funcDecl->get_name() ) ) {
 			if ( params.size() == 0 ) {
-				throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl );
+				throw SemanticError( "Constructors, destructors, and assignment functions 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 );
+				throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a pointer ", funcDecl );
 			}
-			if ( returnVals.size() != 0 ) {
+			if ( InitTweak::isCtorDtor( funcDecl->get_name() ) && returnVals.size() != 0 ) {
 				throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
 			}
Index: src/include/assert.h
===================================================================
--- src/include/assert.h	(revision 4563a956eb56d3c7135208399eafd37c72ea72d3)
+++ src/include/assert.h	(revision d1969a607787c81d78565de2d2aaa145be1680e2)
@@ -22,5 +22,5 @@
 #define assertf(expr, fmt, ...) ((expr) ? static_cast<void>(0) : __assert_fail_f(__VSTRINGIFY__(expr), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, ## __VA_ARGS__ ))
 
-void __assert_fail_f( const char *assertion, const char *file, unsigned int line, const char *function, const char *fmt, ... );
+void __assert_fail_f( const char *assertion, const char *file, unsigned int line, const char *function, const char *fmt, ... ) __attribute__((noreturn));
 
 template<typename T, typename U>
