Index: src/AST/Pass.proto.hpp
===================================================================
--- src/AST/Pass.proto.hpp	(revision 335f2d883b176ca380bde3efee3ab1b59fab5f7b)
+++ src/AST/Pass.proto.hpp	(revision e4b6cf78dcc1d57c24f7b0c95fc9417c02ee0798)
@@ -109,4 +109,6 @@
 	};
 
+	/// "Short hand" to check if this is a valid previsit function
+	/// Mostly used to make the static_assert look (and print) prettier
 	template<typename pass_t, typename node_t>
 	struct is_valid_previsit {
@@ -117,4 +119,7 @@
 	};
 
+	/// Used by previsit implementation
+	/// We need to reassign the result to 'node', unless the function
+	/// returns void, then we just leave 'node' unchanged
 	template<bool is_void>
 	struct __assign;
@@ -134,4 +139,27 @@
 			node = pass.previsit( node );
 			assertf(node, "Previsit must not return NULL");
+		}
+	};
+
+	/// Used by postvisit implementation
+	/// We need to return the result unless the function
+	/// returns void, then we just return the original node
+	template<bool is_void>
+	struct __return;
+
+	template<>
+	struct __return<true> {
+		template<typename pass_t, typename node_t>
+		static inline const node_t * result( pass_t & pass, const node_t * & node ) {
+			pass.postvisit( node );
+			return node;
+		}
+	};
+
+	template<>
+	struct __return<false> {
+		template<typename pass_t, typename node_t>
+		static inline auto result( pass_t & pass, const node_t * & node ) {
+			return pass.postvisit( node );
 		}
 	};
@@ -174,5 +202,9 @@
 		decltype( pass.postvisit( node ), node->accept( *(Visitor*)nullptr ) )
 	{
-		return pass.postvisit( node );
+		return __return<
+			std::is_void<
+				decltype( pass.postvisit( node ) )
+			>::value
+		>::result( pass, node );
 	}
 
