Index: src/AST/Pass.proto.hpp
===================================================================
--- src/AST/Pass.proto.hpp	(revision f4c2f1a02753f281c59f650f4c89475f36279b0c)
+++ src/AST/Pass.proto.hpp	(revision dff645253958b5492b3ea07df67bc6ccd31d9b57)
@@ -107,4 +107,12 @@
 		bool     * m_prev;
 		bool_ref * m_ref;
+	};
+
+	template<typename pass_t, typename node_t>
+	struct is_valid_previsit {
+		using ret_t = decltype( ((pass_t*)nullptr)->previsit( (const node_t *)nullptr ) );
+
+		static constexpr bool value = std::is_void< ret_t >::value ||
+			std::is_base_of<const node_t, typename std::remove_pointer<ret_t>::type >::value;
 	};
 
@@ -127,9 +135,13 @@
 	static inline auto previsit( pass_t & pass, const node_t * & node, int ) -> decltype( pass.previsit( node ), void() ) {
 		static_assert(
-			std::is_base_of<const node_t, typename std::remove_pointer<decltype( pass.previsit( node ) )>::type >::value,
-			"Previsit may not change the type of the node. Use postvisit instead."
+			is_valid_previsit<pass_t, node_t>::value,
+			"Previsit may not change the type of the node. It must return its paremeter or void."
 		);
-		node = pass.previsit( node );
-		assert(node);
+		if(std::is_void< decltype( pass.previsit(node) ) >::value) {
+			pass.previsit( node );
+		} else {
+			node = pass.previsit( node );
+			assert(node);
+		}
 	}
 
@@ -139,5 +151,7 @@
 	// PostVisit : never mutates the passed pointer but may return a different node
 	template<typename pass_t, typename node_t>
-	static inline auto postvisit( pass_t & pass, const node_t * node, int ) -> decltype( pass.postvisit( node ), (const node_t *)nullptr ) {
+	static inline auto postvisit( pass_t & pass, const node_t * node, int ) ->
+		decltype( pass.postvisit( node ), node->accept( *(Visitor*)nullptr ) )
+	{
 		return pass.postvisit( node );
 	}
