Index: src/Common/GC.cc
===================================================================
--- src/Common/GC.cc	(revision 5af7306aa8aedc45c7e1b675f42139b19edd2a7c)
+++ src/Common/GC.cc	(revision 2efe4b8f0141e181a04fcc0495d13a8c7a0a06b9)
@@ -77,7 +77,8 @@
 }
 
-void GC::new_generation() {
+GC_Guard GC::new_generation() {
 	if ( ++g == gens.size() ) { gens.emplace_back(); }  // ensure new generation available
 	mark = !mark;  // switch mark so aged young objects will still be unmarked in old
+	return { *this, g };
 }
 
Index: src/Common/GC.h
===================================================================
--- src/Common/GC.h	(revision 5af7306aa8aedc45c7e1b675f42139b19edd2a7c)
+++ src/Common/GC.h	(revision 2efe4b8f0141e181a04fcc0495d13a8c7a0a06b9)
@@ -16,12 +16,20 @@
 #pragma once
 
+#include <cassert>
 #include <vector>
 
 class GC_Object;
 class BaseSyntaxNode;
+class GC_Guard;
 
 /// Manually traced and called garbage collector
 class GC {
 	friend class GcTracer;
+	friend class GC_Guard;
+
+	/// Collects the youngest generation, placing survivors in previous generation.
+	/// Young generation objects cannot be kept alive by pointers from older generation.
+	/// Older generation is used for subsequent new objects.
+	void collect_young();
 public:
 	/// Gets singleton GC instance
@@ -38,13 +46,8 @@
 
 	/// Start new generation for subsequent new objects
-	void new_generation();
+	GC_Guard new_generation();
 
 	/// Traces all static roots
 	void trace_static_roots();
-
-	/// Collects the youngest generation, placing survivors in previous generation.
-	/// Young generation objects cannot be kept alive by pointers from older generation.
-	/// Older generation is used for subsequent new objects.
-	void collect_young();
 
 	/// Collects oldest generation; use oldest generation afterward.
@@ -68,6 +71,22 @@
 };
 
+/// Cleanup object for young generation
+class GC_Guard {
+	friend class GC;
+
+	GC& gc;      ///< GC associated with
+	unsigned g;  ///< Generation constructed for
+
+	GC_Guard( GC& gc, unsigned g ) : gc(gc), g(g) {}
+
+public:
+	~GC_Guard() {
+		assert( gc.g == g && "collecting current generation" );
+		gc.collect_young();
+	}
+};
+
 /// Use young generation until next collection
-inline void new_generation() { GC::get().new_generation(); }
+inline GC_Guard new_generation() { return GC::get().new_generation(); }
 
 // /// no-op default trace
@@ -84,14 +103,13 @@
 }
 
-/// Traces young-generation roots and does a young collection
+/// Traces roots without collecting
 template<typename... Args>
-inline void collect_young(Args&... roots) {
+inline void trace(Args&... roots) {
 	GC& gc = GC::get();
 	traceAll(gc, roots...);
 	gc.trace_static_roots();
-	gc.collect_young();
 }
 
-/// Traces roots and collects other elements
+/// Traces roots and collects other elements; should not be any young generations live
 template<typename... Args>
 inline void collect(Args&... roots) {
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 5af7306aa8aedc45c7e1b675f42139b19edd2a7c)
+++ src/GenPoly/Box.cc	(revision 2efe4b8f0141e181a04fcc0495d13a8c7a0a06b9)
@@ -283,6 +283,6 @@
 		for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); 
 				param != otypeParams.end(); ++param ) {
-			TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
-			std::string paramName = mangleType( &paramType );
+			auto paramType = new TypeInstType( Type::Qualifiers(), (*param)->get_name(), *param );
+			std::string paramName = mangleType( paramType );
 			layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), Type::StorageClasses(), LinkageSpec::Cforall, 0, sizeAlignType->clone(), 0 ) );
 			layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( paramName ), Type::StorageClasses(), LinkageSpec::Cforall, 0, sizeAlignType->clone(), 0 ) );
@@ -1436,6 +1436,6 @@
 			if ( Type * base = typeDecl->base ) {
 				// add size/align variables for opaque type declarations
-				TypeInstType inst( Type::Qualifiers(), typeDecl->name, typeDecl );
-				std::string typeName = mangleType( &inst );
+				auto inst = new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl );
+				std::string typeName = mangleType( inst );
 				Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 5af7306aa8aedc45c7e1b675f42139b19edd2a7c)
+++ src/ResolvExpr/Resolver.cc	(revision 2efe4b8f0141e181a04fcc0495d13a8c7a0a06b9)
@@ -148,5 +148,5 @@
 			assertf( untyped, "expected a non-null expression." );
 
-			new_generation();  // set up GC young generation for this top-level expression
+			auto guard = new_generation();  // set up GC generation for this top-level expression
 
 			TypeEnvironment env;
@@ -177,5 +177,4 @@
 			findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) );
 			if ( winners.size() == 0 ) {
-				collect_young();
 				SemanticError( untyped, toString( 
 					"No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""), 
@@ -189,5 +188,4 @@
 				printAlts( winners, stream, 1 );
 				
-				collect_young();
 				SemanticError( untyped->location, stream.str() );
 			}
@@ -196,10 +194,10 @@
 			Alternative & choice = winners.front();
 			if ( findDeletedExpr( choice.expr ) ) {
-				collect_young( choice.expr );
+				trace( choice.expr );
 				SemanticError( choice.expr, 
 					"Unique best alternative includes deleted identifier in " );
 			}
 			alt = std::move( choice );
-			collect_young( alt );
+			trace( alt );
 		}
 
Index: src/SynTree/GcTracer.h
===================================================================
--- src/SynTree/GcTracer.h	(revision 5af7306aa8aedc45c7e1b675f42139b19edd2a7c)
+++ src/SynTree/GcTracer.h	(revision 2efe4b8f0141e181a04fcc0495d13a8c7a0a06b9)
@@ -20,4 +20,5 @@
 #include "BaseSyntaxNode.h"
 #include "Expression.h"
+#include "Label.h"
 #include "Type.h"
 
@@ -53,4 +54,8 @@
 	}
 
+	void postvisit( AggregateDecl* decl ) {
+		acceptAll( decl->attributes, *visitor );
+	}
+
 	void postvisit( DeclarationWithType* decl ) {
 		maybeAccept( decl->asmName, *visitor );
@@ -73,4 +78,10 @@
 	}
 
+	void postvisit( UniqueExpr* expr ) {
+		postvisit( static_cast<Expression*>(expr) );
+		maybeAccept( expr->object, *visitor );
+		maybeAccept( expr->var, *visitor );
+	}
+
 	void postvisit( UntypedExpr* expr ) {
 		postvisit( static_cast<Expression*>(expr) );
@@ -81,4 +92,17 @@
 		postvisit( static_cast<Expression*>(expr) );
 		maybeAccept( expr->var, *visitor );  // not in PassVisitor because it causes cycle
+	}
+
+private:
+	void visit( Label& lbl ) {
+		acceptAll( lbl.get_attributes(), *visitor );
+		maybeAccept( lbl.get_statement(), *visitor );  // xxx - not sure this is needed...
+	}
+
+public:
+	void postvisit( Statement* stmt ) {
+		for ( Label& l : stmt->labels ) {
+			visit( l );
+		}
 	}
 
