Index: libcfa/src/heap.cfa
===================================================================
--- libcfa/src/heap.cfa	(revision 4bc27c03d9f04802e4c9ca0b6c465377c0ed8763)
+++ libcfa/src/heap.cfa	(revision 447b0d2b78a565216fda1aae8b888fe3bc1640be)
@@ -1239,8 +1239,11 @@
 	size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
 
-	if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match
-		if ( oalign > libAlign() ) {					// fake header ?
-			headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
-		} // if
+	if ( oalign == nalign && size <= odsize && odsize <= size * 2 ) { // <= alignment and new alignment are same, allow 50% wasted storage for smaller size
+		header->kind.real.blockSize &= -2;			// turn off 0 fill
+		header->kind.real.size = size;				// reset allocation size
+		return oaddr;
+	} // if
+	if ( oalign < nalign && (uintptr_t)oaddr % nalign == 0 && oalign > libAlign() ) { // <= alignment and new alignment happens to match, and oaddr has a fake header
+		headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
 		if ( size <= odsize && odsize <= size * 2 ) {	// allow 50% wasted storage for smaller size
 			header->kind.real.blockSize &= -2;			// turn off 0 fill
@@ -1282,8 +1285,9 @@
 	headers( "realloc", oaddr, header, freeElem, bsize, oalign );
 
-	if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match
-		if ( oalign > libAlign() ) {					// fake header ?
-			headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
-		} // if
+	if ( oalign == nalign ) { // <= alignment and new alignment are same
+		return realloc( oaddr, size );
+	} // if
+	if ( oalign < nalign && (uintptr_t)oaddr % nalign == 0 && oalign > libAlign() ) { // <= alignment and new alignment happens to match, and oaddr has a fake header
+		headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
 		return realloc( oaddr, size );
 	} // if
Index: libcfa/src/stdlib.hfa
===================================================================
--- libcfa/src/stdlib.hfa	(revision 4bc27c03d9f04802e4c9ca0b6c465377c0ed8763)
+++ libcfa/src/stdlib.hfa	(revision 447b0d2b78a565216fda1aae8b888fe3bc1640be)
@@ -179,12 +179,9 @@
 
 		if ( Resize ) {
-//printf("1. $alloc_internal got: %p %p %lu %lu\n", Resize, Realloc, Align, Dim); // these prints are temporary
 			ptr = (T*) (void *) resize( (void *)Resize, Align, Dim * size );
 		} else if ( Realloc ) {
 			if (Fill.tag != '0') copy_end = min(malloc_size( Realloc ), Dim * size);
-//printf("2. $alloc_internal got: %p %p %lu %lu\n", Resize, Realloc, Align, Dim);
 			ptr = (T*) (void *) realloc( (void *)Realloc, Align, Dim * size );
 		} else {
-//printf("3. $alloc_internal got: %p %p %lu %lu\n", Resize, Realloc, Align, Dim);
 			ptr = (T*) (void *) memalign( Align, Dim * size );
 		}
Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision 4bc27c03d9f04802e4c9ca0b6c465377c0ed8763)
+++ src/AST/Pass.hpp	(revision 447b0d2b78a565216fda1aae8b888fe3bc1640be)
@@ -48,4 +48,6 @@
 //
 // Several additional features are available through inheritance
+// | PureVisitor           - makes the visitor pure, it never modifies nodes in place and always
+//                           clones nodes it needs to make changes to
 // | WithTypeSubstitution  - provides polymorphic const TypeSubstitution * env for the
 //                           current expression
@@ -267,5 +269,5 @@
 /// Keep track of the polymorphic const TypeSubstitution * env for the current expression
 
-/// marker to force shallow copies in pass visit
+/// If used the visitor will always clone nodes.
 struct PureVisitor {};
 
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 4bc27c03d9f04802e4c9ca0b6c465377c0ed8763)
+++ src/AST/Pass.impl.hpp	(revision 447b0d2b78a565216fda1aae8b888fe3bc1640be)
@@ -21,5 +21,4 @@
 
 #include "AST/TypeSubstitution.hpp"
-// #include "AST/Copy.hpp"
 
 #define VISIT_START( node ) \
@@ -329,5 +328,4 @@
 
 		if( __pass::differs(old_val, new_val) ) {
-			// auto new_parent = mutate(parent);
 			auto new_parent = __pass::mutate<core_t>(parent);
 			new_parent->*child = new_val;
Index: src/AST/TypeSubstitution.hpp
===================================================================
--- src/AST/TypeSubstitution.hpp	(revision 4bc27c03d9f04802e4c9ca0b6c465377c0ed8763)
+++ src/AST/TypeSubstitution.hpp	(revision 447b0d2b78a565216fda1aae8b888fe3bc1640be)
@@ -46,5 +46,4 @@
 	template< typename SynTreeClass >
 	struct ApplyResult {
-		// const SynTreeClass * node;
 		ast::ptr<SynTreeClass> node;
 		int count;
@@ -187,5 +186,4 @@
 	assert( input );
 	Pass<Substituter> sub( *this, false );
-//	input = strict_dynamic_cast< const SynTreeClass * >( deepCopy(input)->accept( sub ) );
 	input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) );
 	return { input, sub.core.subCount };
@@ -196,5 +194,4 @@
 	assert( input );
 	Pass<Substituter> sub( *this, true );
-//	input = strict_dynamic_cast< const SynTreeClass * >( deepCopy(input)->accept( sub ) );
 	input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) );
 	return { input, sub.core.subCount };
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 4bc27c03d9f04802e4c9ca0b6c465377c0ed8763)
+++ src/ResolvExpr/Unify.cc	(revision 447b0d2b78a565216fda1aae8b888fe3bc1640be)
@@ -1113,6 +1113,4 @@
 			ast::Pass<TtypeExpander_new> expander{ tenv };
 
-			// ast::ptr<ast::TupleType> tuplec = tuple;
-			// ast::ptr<ast::TupleType> tuple2c = tuple2;
 			const ast::Type * flat = tuple->accept( expander );
 			const ast::Type * flat2 = tuple2->accept( expander );
Index: tests/.expect/alloc2.txt
===================================================================
--- tests/.expect/alloc2.txt	(revision 447b0d2b78a565216fda1aae8b888fe3bc1640be)
+++ tests/.expect/alloc2.txt	(revision 447b0d2b78a565216fda1aae8b888fe3bc1640be)
@@ -0,0 +1,6 @@
+PASSED alloc tests
+
+PASSED alloc tests (aligned struct)
+
+(if applicable) alignment error below indicates memory trashing caused by test_use.
+
Index: tests/alloc2.cfa
===================================================================
--- tests/alloc2.cfa	(revision 4bc27c03d9f04802e4c9ca0b6c465377c0ed8763)
+++ tests/alloc2.cfa	(revision 447b0d2b78a565216fda1aae8b888fe3bc1640be)
@@ -1,6 +1,2 @@
-/*
-	some tests are commented-out because of resize/realloc bug from 0p. They should be uncommented after that bug is resolved.
-*/
-
 #include <malloc.h>										// malloc_usable_size
 #include <stdint.h>										// uintptr_t
@@ -20,8 +16,5 @@
 	if (!passed) {
 		printf("failed test %3d: %4lu %4lu but got %4lu ( %3lu ) %4lu\n", tests_total, size, align, malloc_size(ip), malloc_usable_size(ip), malloc_alignment(ip));
-//		if (last_failed != tests_total) {
-			tests_failed += 1;
-//			last_failed = tests_total;
-//		}
+		tests_failed += 1;
 	}
 }
@@ -34,8 +27,5 @@
 	if (!passed) {
 		printf("failed test %3d: fill C\n", tests_total);
-//		if (last_failed != tests_total) {
-			tests_failed += 1;
-//			last_failed = tests_total;
-//		}
+		tests_failed += 1;
 	}
 }
@@ -48,8 +38,5 @@
 	if (!passed) {
 		printf("failed test %3d: fill int\n", tests_total);
-//		if (last_failed != tests_total) {
-			tests_failed += 1;
-//			last_failed = tests_total;
-//		}
+		tests_failed += 1;
 	}
 }
@@ -60,8 +47,5 @@
 	if (!passed) {
 		printf("failed test %3d: fill int A\n", tests_total);
-//		if (last_failed != tests_total) {
-			tests_failed += 1;
-//			last_failed = tests_total;
-//		}
+		tests_failed += 1;
 	}
 }
@@ -74,8 +58,5 @@
 	if (!passed) {
 		printf("failed test %3d: fill T1\n", tests_total);
-//		if (last_failed != tests_total) {
-			tests_failed += 1;
-//			last_failed = tests_total;
-//		}
+		tests_failed += 1;
 	}
 }
@@ -86,8 +67,5 @@
 	if (!passed) {
 		printf("failed test %3d: fill T1 A\n", tests_total);
-//		if (last_failed != tests_total) {
-			tests_failed += 1;
-//			last_failed = tests_total;
-//		}
+		tests_failed += 1;
 	}
 }
@@ -100,8 +78,5 @@
 	if (!passed) {
 		printf("failed test %3d: use int\n", tests_total);
-//		if (last_failed != tests_total) {
-			tests_failed += 1;
-//			last_failed = tests_total;
-//		}
+		tests_failed += 1;
 	}
 }
@@ -114,8 +89,5 @@
 	if (!passed) {
 		printf("failed test %3d: use T1\n", tests_total);
-//		if (last_failed != tests_total) {
-			tests_failed += 1;
-//			last_failed = tests_total;
-//		}
+		tests_failed += 1;
 	}
 }
@@ -331,7 +303,7 @@
 	free(ip);
 
-//	ip = alloc( 0, ((int*)0p)`realloc, FillT`fill );
-//	est_base(ip, 0, libAlign);
-//	free(ip);
+	ip = alloc( 0, ((int*)0p)`realloc, FillT`fill );
+	test_base(ip, 0, libAlign);
+	free(ip);
 
 	ip = alloc( align`align );
@@ -356,8 +328,8 @@
 	free(ip);
 
-//	ip = alloc( ((int*)0p)`realloc, align`align );
-//	est_base(ip, elemSize, align);
-//	est_use(ip, elemSize / elemSize);
-//	free(ip);
+	ip = alloc( ((int*)0p)`realloc, align`align );
+	test_base(ip, elemSize, align);
+	test_use(ip, elemSize / elemSize);
+	free(ip);
 
 	dp = alloc( dim );
@@ -367,8 +339,8 @@
 	free(ip);
 
-//	ip = alloc( ((double*)0p)`resize, align`align );
-//	est_base(ip, elemSize, align);
-//	est_use(ip, elemSize / elemSize);
-//	free(ip);
+	ip = alloc( ((double*)0p)`resize, align`align );
+	test_base(ip, elemSize, align);
+	test_use(ip, elemSize / elemSize);
+	free(ip);
 
 	op = alloc( dim, ((int)0xdeadbeef)`fill);
@@ -384,12 +356,12 @@
 	free(ip);
 
-//	ip = alloc( dim, ((int*)0p)`realloc, align`align );
-//	est_base(ip, size, align);
-//	est_use(ip, size / elemSize);
-//	free(ip);
-
-//	ip = alloc( 0, ((int*)0p)`realloc, align`align );
-//	est_base(ip, 0, align);
-//	free(ip);
+	ip = alloc( dim, ((int*)0p)`realloc, align`align );
+	test_base(ip, size, align);
+	test_use(ip, size / elemSize);
+	free(ip);
+
+	ip = alloc( 0, ((int*)0p)`realloc, align`align );
+	test_base(ip, 0, libAlign);
+	free(ip);
 
 	ip = alloc( align`align, FillC`fill );
@@ -462,13 +434,13 @@
 	free(ip);
 
-//	ip = alloc( dim, ((int*)0p)`realloc, align`align, FillC`fill );
-//	est_base(ip, size, align);
-//	est_fill(ip, 0, size, FillC);
-//	est_use(ip, size / elemSize);
-//	free(ip);
-
-//	ip = alloc( 0, ((int*)0p)`realloc, align`align, FillC`fill );
-//	est_base(ip, 0, align);
-//	free(ip);
+	ip = alloc( dim, ((int*)0p)`realloc, align`align, FillC`fill );
+	test_base(ip, size, align);
+	test_fill(ip, 0, size, FillC);
+	test_use(ip, size / elemSize);
+	free(ip);
+
+	ip = alloc( 0, ((int*)0p)`realloc, align`align, FillC`fill );
+	test_base(ip, 0, libAlign);
+	free(ip);
 
 	op = alloc( dim, ((int)0xdeadbeef)`fill );
@@ -499,13 +471,13 @@
 	free(ip);
 
-//	ip = alloc( dim, ((int*)0p)`realloc, align`align, FillT`fill );
-//	est_base(ip, size, align);
-//	est_fill(ip, 0, dim, FillT);
-//	est_use(ip, size / elemSize);
-//	free(ip);
-
-//	ip = alloc( 0, ((int*)0p)`realloc, align`align, FillT`fill );
-//	est_base(ip, 0, align);
-//	free(ip);
+	ip = alloc( dim, ((int*)0p)`realloc, align`align, FillT`fill );
+	test_base(ip, size, align);
+	test_fill(ip, 0, dim, FillT);
+	test_use(ip, size / elemSize);
+	free(ip);
+
+	ip = alloc( 0, ((int*)0p)`realloc, align`align, FillT`fill );
+	test_base(ip, 0, libAlign);
+	free(ip);
 
 	if (tests_failed == 0) printf("PASSED alloc tests\n\n");
@@ -704,7 +676,7 @@
 	free(t1p);
 
-//	t1p = alloc( (T1*)0p, 0, FillT1 );
-//	est_base(t1p, 0, tAlign);
-//	free(t1p);
+	t1p = alloc( 0, ((T1*)0p)`realloc, FillT1`fill );
+	test_base(t1p, 0, libAlign);
+	free(t1p);
 
 	t1p = alloc( align`align );
@@ -729,8 +701,8 @@
 	free(t1p);
 
-//	t1p = alloc( ((T1*)0p)`realloc, align`align );
-//	est_base(t1p, elemSize, align);
-//	est_use(t1p, elemSize / elemSize);
-//	free(t1p);
+	t1p = alloc( ((T1*)0p)`realloc, align`align );
+	test_base(t1p, elemSize, align);
+	test_use(t1p, elemSize / elemSize);
+	free(t1p);
 
 	dp = alloc( dim );
@@ -740,8 +712,8 @@
 	free(t1p);
 
-//	t1p = alloc( ((double*)0p)`resize, align`align );
-//	est_base(t1p, elemSize, align);
-//	est_use(t1p, elemSize / elemSize);
-//	free(t1p);
+	t1p = alloc( ((double*)0p)`resize, align`align );
+	test_base(t1p, elemSize, align);
+	test_use(t1p, elemSize / elemSize);
+	free(t1p);
 
 	t1op = alloc( dim, ((T1){0xdeadbeef})`fill );
@@ -757,12 +729,12 @@
 	free(t1p);
 
-//	t1p = alloc( dim, ((T1*)0p)`realloc, align`align );
-//	est_base(t1p, size, align);
-//	est_use(t1p, size / elemSize);
-//	free(t1p);
-
-//	t1p = alloc( 0, ((T1*)0p)`realloc, align`align );
-//	est_base(t1p, 0, align);
-//	free(t1p);
+	t1p = alloc( dim, ((T1*)0p)`realloc, align`align );
+	test_base(t1p, size, align);
+	test_use(t1p, size / elemSize);
+	free(t1p);
+
+	t1p = alloc( 0, ((T1*)0p)`realloc, align`align );
+	test_base(t1p, 0, libAlign);
+	free(t1p);
 
 	t1p = alloc( align`align, FillC`fill );
@@ -835,13 +807,13 @@
 	free(t1p);
 
-//	t1p = alloc( dim, ((T1*)0p)`realloc, align`align, FillC`fill );
-//	est_base(t1p, size, align);
-//	est_fill(t1p, 0, size, FillC);
-//	est_use(t1p, size / elemSize);
-//	free(t1p);
-
-//	t1p = alloc( 0, ((T1*)0p)`realloc, align`align, FillC`fill );
-//	est_base(t1p, 0, align);
-//	free(t1p);
+	t1p = alloc( dim, ((T1*)0p)`realloc, align`align, FillC`fill );
+	test_base(t1p, size, align);
+	test_fill(t1p, 0, size, FillC);
+	test_use(t1p, size / elemSize);
+	free(t1p);
+
+	t1p = alloc( 0, ((T1*)0p)`realloc, align`align, FillC`fill );
+	test_base(t1p, 0, libAlign);
+	free(t1p);
 
 	t1op = alloc( dim, ((T1){0xdeadbeef})`fill);
@@ -872,13 +844,13 @@
 	free(t1p);
 
-//	t1p = alloc( dim, ((T1*)0p)`realloc, align`aling, FillT1`fill );
-//	est_base(t1p, size, align);
-//	est_fill(t1p, 0, dim, FillT1);
-//	est_use(t1p, size / elemSize);
-//	free(t1p);
-
-//	t1p = alloc( 0, ((T1*)0p)`realloc, align`align, FillT1`fill );
-//	est_base(t1p, 0, align);
-//	free(t1p);
+	t1p = alloc( dim, ((T1*)0p)`realloc, align`align, FillT1`fill );
+	test_base(t1p, size, align);
+	test_fill(t1p, 0, dim, FillT1);
+	test_use(t1p, size / elemSize);
+	free(t1p);
+
+	t1p = alloc( 0, ((T1*)0p)`realloc, align`align, FillT1`fill );
+	test_base(t1p, 0, libAlign);
+	free(t1p);
 
 	if (tests_failed == 0) printf("PASSED alloc tests (aligned struct)\n\n");
Index: tests/malloc.cfa
===================================================================
--- tests/malloc.cfa	(revision 4bc27c03d9f04802e4c9ca0b6c465377c0ed8763)
+++ tests/malloc.cfa	(revision 447b0d2b78a565216fda1aae8b888fe3bc1640be)
@@ -252,4 +252,16 @@
 
 	ip = (int *) (void *) malloc( size );
+	ip = (int *) (void *) resize( (void *) ip, libAlign, size / 2 );
+	test_base(ip, size / 2, libAlign);
+	test_use(ip);
+	free(ip);
+
+	ip = (int *) (void *) aligned_alloc( align, size );
+	ip = (int *) (void *) resize( (void *) ip, align, size / 2 );
+	test_base(ip, size / 2, align);
+	test_use(ip);
+	free(ip);
+
+	ip = (int *) (void *) malloc( size );
 	ip = (int *) (void *) resize( (void *) ip, align, size / 4 );
 	test_base(ip, size / 4, align);
@@ -270,4 +282,18 @@
 	ip = (int *) (void *) resize( 0p, align, size );
 	test_base(ip, size, align);
+	test_use(ip);
+	free(ip);
+
+	ip = (int *) (void *) calloc( dim, elemSize );
+	ip = (int *) (void *) realloc( (void *) ip, libAlign, size / 2 );
+	test_base(ip, size / 2, libAlign);
+	test_fill(ip, 0, size / 2, '\0');
+	test_use(ip);
+	free(ip);
+
+	ip = (int *) (void *) cmemalign( align, dim, elemSize );
+	ip = (int *) (void *) realloc( (void *) ip, align, size / 2 );
+	test_base(ip, size / 2, align);
+	test_fill(ip, 0, size / 2, '\0');
 	test_use(ip);
 	free(ip);
@@ -437,5 +463,5 @@
 	else printf("failed CFA malloc tests : %d/%d\n\n", tests_failed, tests_total);
 
-	// testing CFA malloc
+	// testing CFA malloc with aligned struct
 
 	elemSize = sizeof(T1);
@@ -518,15 +544,13 @@
 	free(tp);
 
-/*
 	tp = realloc( (T1*)0p, size  );
-	est_base(tp, size , tAlign );
-	est_use(tp);
+	test_base(tp, size , tAlign );
+	test_use(tp);
 	free(tp);
 
 	tp = realloc( (T1*)0p, size );
-	est_base(tp, size, tAlign );
-	est_use(tp);
-	free(tp);
-*/
+	test_base(tp, size, tAlign );
+	test_use(tp);
+	free(tp);
 
 	tp = memalign( align );
