Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/AST/Convert.cpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -93,8 +93,8 @@
 	};
 
-    template<typename T>
-    Getter<T> get() {
-        return Getter<T>{ *this };
-    }
+	template<typename T>
+	Getter<T> get() {
+		return Getter<T>{ *this };
+	}
 
 	Label makeLabel(Statement * labelled, const ast::Label& label) {
@@ -1651,4 +1651,5 @@
 			// GET_ACCEPT_1(type, FunctionType),
 			std::move(forall),
+			std::move(assertions),
 			std::move(paramVars),
 			std::move(returnVars),
@@ -1664,5 +1665,4 @@
 		cache.emplace( old, decl );
 
-		decl->assertions = std::move(assertions);
 		decl->withExprs = GET_ACCEPT_V(withExprs, Expr);
 		decl->stmts = GET_ACCEPT_1(statements, CompoundStmt);
Index: src/AST/Copy.cpp
===================================================================
--- src/AST/Copy.cpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/AST/Copy.cpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -10,6 +10,6 @@
 // Created On       : Thr Nov 11  9:16:00 2019
 // Last Modified By : Andrew Beach
-// Last Modified On : Thr Nov 11  9:28:00 2021
-// Update Count     : 0
+// Last Modified On : Tue May  3 16:28:00 2022
+// Update Count     : 1
 //
 
@@ -77,4 +77,8 @@
 	}
 
+	void postvisit( const UniqueExpr * node ) {
+		readonlyInsert( &node->object );
+	}
+
 	void postvisit( const MemberExpr * node ) {
 		readonlyInsert( &node->member );
Index: src/AST/Decl.cpp
===================================================================
--- src/AST/Decl.cpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/AST/Decl.cpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Thu May 9 10:00:00 2019
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jan 12 16:54:55 2021
-// Update Count     : 23
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu May  5 12:10:00 2022
+// Update Count     : 24
 //
 
@@ -53,5 +53,5 @@
 // --- FunctionDecl
 
-FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name, 
+FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name,
 	std::vector<ptr<TypeDecl>>&& forall,
 	std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
@@ -74,4 +74,30 @@
 	}
 	this->type = ftype;
+}
+
+FunctionDecl::FunctionDecl( const CodeLocation & location, const std::string & name,
+	std::vector<ptr<TypeDecl>>&& forall, std::vector<ptr<DeclWithType>>&& assertions,
+	std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
+	CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage,
+	std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs)
+: DeclWithType( location, name, storage, linkage, std::move(attrs), fs ),
+		params( std::move(params) ), returns( std::move(returns) ),
+		type_params( std::move( forall) ), assertions( std::move( assertions ) ),
+		type( nullptr ), stmts( stmts ) {
+	FunctionType * type = new FunctionType( (isVarArgs) ? VariableArgs : FixedArgs );
+	for ( auto & param : this->params ) {
+		type->params.emplace_back( param->get_type() );
+	}
+	for ( auto & ret : this->returns ) {
+		type->returns.emplace_back( ret->get_type() );
+	}
+	for ( auto & param : this->type_params ) {
+		type->forall.emplace_back( new TypeInstType( param ) );
+	}
+	for ( auto & assertion : this->assertions ) {
+		type->assertions.emplace_back(
+			new VariableExpr( assertion->location, assertion ) );
+	}
+	this->type = type;
 }
 
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/AST/Decl.hpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Thu May 9 10:00:00 2019
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Mar 12 18:25:05 2021
-// Update Count     : 32
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu May  5 12:09:00 2022
+// Update Count     : 33
 //
 
@@ -135,10 +135,20 @@
 	std::vector< ptr<Expr> > withExprs;
 
+	// The difference between the two constructors is in how they handle
+	// assertions. The first constructor uses the assertions from the type
+	// parameters, in the style of the old ast, and puts them on the type.
+	// The second takes an explicite list of assertions and builds a list of
+	// references to them on the type.
+
 	FunctionDecl( const CodeLocation & loc, const std::string & name, std::vector<ptr<TypeDecl>>&& forall,
 		std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
 		CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C,
 		std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false);
-	// : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)),
-	//  stmts( stmts ) {}
+
+	FunctionDecl( const CodeLocation & location, const std::string & name,
+		std::vector<ptr<TypeDecl>>&& forall, std::vector<ptr<DeclWithType>>&& assertions,
+		std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
+		CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C,
+		std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false);
 
 	const Type * get_type() const override;
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/AST/Expr.hpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -784,5 +784,5 @@
 public:
 	ptr<Expr> expr;
-	ptr<ObjectDecl> object;
+	readonly<ObjectDecl> object;
 	ptr<VariableExpr> var;
 	unsigned long long id;
Index: src/AST/Label.hpp
===================================================================
--- src/AST/Label.hpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/AST/Label.hpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -34,5 +34,5 @@
 	std::vector< ptr<Attribute> > attributes;
 
-	Label( CodeLocation loc, const std::string& name = "",
+	Label( const CodeLocation& loc, const std::string& name = "",
 		std::vector<ptr<Attribute>> && attrs = std::vector<ptr<Attribute>>{} )
 	: location( loc ), name( name ), attributes( attrs ) {}
Index: src/AST/Node.hpp
===================================================================
--- src/AST/Node.hpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/AST/Node.hpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 8 10:27:04 2019
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Mar 25 10:33:00 2022
-// Update Count     : 7
+// Last Modified On : Mon May  9 10:20:00 2022
+// Update Count     : 8
 //
 
@@ -49,5 +49,9 @@
 
 	bool unique() const { return strong_count == 1; }
-	bool isManaged() const {return strong_count > 0; }
+	bool isManaged() const { return strong_count > 0; }
+	bool isReferenced() const { return weak_count > 0; }
+	bool isStable() const {
+		return (1 == strong_count || (1 < strong_count && 0 == weak_count));
+	}
 
 private:
Index: src/AST/Pass.proto.hpp
===================================================================
--- src/AST/Pass.proto.hpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/AST/Pass.proto.hpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -131,6 +131,6 @@
 	template< typename node_t >
 	struct result1 {
-		bool differs;
-		const node_t * value;
+		bool differs = false;
+		const node_t * value = nullptr;
 
 		template< typename object_t, typename super_t, typename field_t >
@@ -151,5 +151,5 @@
 		};
 
-		bool differs;
+		bool differs = false;
 		container_t< delta > values;
 
@@ -167,5 +167,5 @@
 	template< template<class...> class container_t, typename node_t >
 	struct resultN {
-		bool differs;
+		bool differs = false;
 		container_t<ptr<node_t>> values;
 
Index: src/AST/Stmt.cpp
===================================================================
--- src/AST/Stmt.cpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/AST/Stmt.cpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -9,12 +9,12 @@
 // Author           : Aaron B. Moss
 // Created On       : Wed May  8 13:00:00 2019
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Feb  2 19:01:20 2022
-// Update Count     : 3
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue May  3 15:18:20 2022
+// Update Count     : 4
 //
 
 #include "Stmt.hpp"
 
-
+#include "Copy.hpp"
 #include "DeclReplacer.hpp"
 #include "Type.hpp"
@@ -23,5 +23,17 @@
 
 // --- CompoundStmt
-CompoundStmt::CompoundStmt( const CompoundStmt& other ) : Stmt(other), kids(other.kids) {
+CompoundStmt::CompoundStmt( const CompoundStmt& other ) : Stmt(other), kids() {
+	// Statements can have weak references to them, if that happens inserting
+	// the original node into the new list will put the original node in a
+	// bad state, where it cannot be mutated. To avoid this, just perform an
+	// additional shallow copy on the statement.
+	for ( const Stmt * kid : other.kids ) {
+		if ( kid->isReferenced() ) {
+			kids.emplace_back( ast::shallowCopy( kid ) );
+		} else {
+			kids.emplace_back( kid );
+		}
+	}
+
 	// when cloning a compound statement, we may end up cloning declarations which
 	// are referred to by VariableExprs throughout the block. Cloning a VariableExpr
Index: src/AST/Stmt.hpp
===================================================================
--- src/AST/Stmt.hpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/AST/Stmt.hpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -58,5 +58,5 @@
 	// cannot be, they are sub-types of this type, for organization.
 
-    StmtClause( const CodeLocation & loc )
+	StmtClause( const CodeLocation & loc )
 		: ParseNode(loc) {}
 
@@ -396,16 +396,16 @@
 class WaitForClause final : public StmtClause {
   public:
-    ptr<Expr> target_func;
-    std::vector<ptr<Expr>> target_args;
-    ptr<Stmt> stmt;
-    ptr<Expr> cond;
-
-    WaitForClause( const CodeLocation & loc )
+	ptr<Expr> target_func;
+	std::vector<ptr<Expr>> target_args;
+	ptr<Stmt> stmt;
+	ptr<Expr> cond;
+
+	WaitForClause( const CodeLocation & loc )
 		: StmtClause( loc ) {}
 
 	const WaitForClause * accept( Visitor & v ) const override { return v.visit( this ); }
   private:
-    WaitForClause * clone() const override { return new WaitForClause{ *this }; }
-    MUTATE_FRIEND
+	WaitForClause * clone() const override { return new WaitForClause{ *this }; }
+	MUTATE_FRIEND
 };
 
Index: src/AST/Util.cpp
===================================================================
--- src/AST/Util.cpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/AST/Util.cpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Util.hpp -- General utilities for working with the AST.
+// Util.cpp -- General utilities for working with the AST.
 //
 // Author           : Andrew Beach
 // Created On       : Wed Jan 19  9:46:00 2022
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Mar 11 18:07:00 2022
-// Update Count     : 1
+// Last Modified On : Wed May 11 16:16:00 2022
+// Update Count     : 3
 //
 
@@ -46,9 +46,40 @@
 
 /// Check that every note that can has a set CodeLocation.
-struct SetCodeLocationsCore {
-	void previsit( const ParseNode * node ) {
-		assert( node->location.isSet() );
+void isCodeLocationSet( const ParseNode * node ) {
+	assert( node->location.isSet() );
+}
+
+void areLabelLocationsSet( const Stmt * stmt ) {
+	for ( const Label& label : stmt->labels ) {
+		assert( label.location.isSet() );
 	}
-};
+}
+
+/// Make sure the reference counts are in a valid combination.
+void isStable( const Node * node ) {
+	assert( node->isStable() );
+}
+
+/// Check that a FunctionDecl is synchronized with it's FunctionType.
+void functionDeclMatchesType( const FunctionDecl * decl ) {
+	// The type is a cache of sorts, if it is missing that is only a
+	// problem if isTypeFixed is set.
+	if ( decl->isTypeFixed ) {
+		assert( decl->type );
+	} else if ( !decl->type ) {
+		return;
+	}
+
+	const FunctionType * type = decl->type;
+
+	// Check that `type->forall` corresponds with `decl->type_params`.
+	assert( type->forall.size() == decl->type_params.size() );
+	// Check that `type->assertions` corresponds with `decl->assertions`.
+	assert( type->assertions.size() == decl->assertions.size() );
+	// Check that `type->params` corresponds with `decl->params`.
+	assert( type->params.size() == decl->params.size() );
+	// Check that `type->returns` corresponds with `decl->returns`.
+	assert( type->returns.size() == decl->returns.size() );
+}
 
 struct InvariantCore {
@@ -56,13 +87,23 @@
 	// None of the passes should make changes so ordering doesn't matter.
 	NoStrongCyclesCore no_strong_cycles;
-	SetCodeLocationsCore set_code_locations;
 
 	void previsit( const Node * node ) {
 		no_strong_cycles.previsit( node );
+		isStable( node );
 	}
 
 	void previsit( const ParseNode * node ) {
-		no_strong_cycles.previsit( node );
-		set_code_locations.previsit( node );
+		previsit( (const Node *)node );
+		isCodeLocationSet( node );
+	}
+
+	void previsit( const FunctionDecl * node ) {
+		previsit( (const ParseNode *)node );
+		functionDeclMatchesType( node );
+	}
+
+	void previsit( const Stmt * node ) {
+		previsit( (const ParseNode *)node );
+		areLabelLocationsSet( node );
 	}
 
Index: src/Common/CodeLocationTools.cpp
===================================================================
--- src/Common/CodeLocationTools.cpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/Common/CodeLocationTools.cpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -10,6 +10,6 @@
 // Created On       : Fri Dec  4 15:42:00 2020
 // Last Modified By : Andrew Beach
-// Last Modified On : Mon Mar 14 15:14:00 2022
-// Update Count     : 4
+// Last Modified On : Wed May 11 16:16:00 2022
+// Update Count     : 5
 //
 
@@ -24,64 +24,71 @@
 namespace {
 
-// There are a lot of helpers in this file that could be used much more
-// generally if anyone has another use for them.
-
-// Check if a node type has a code location.
-template<typename node_t>
-struct has_code_location : public std::is_base_of<ast::ParseNode, node_t> {};
-
-template<typename node_t, bool has_location>
-struct __GetCL;
-
-template<typename node_t>
-struct __GetCL<node_t, true> {
-	static inline CodeLocation const * get( node_t const * node ) {
-		return &node->location;
-	}
-
-	static inline CodeLocation * get( node_t * node ) {
-		return &node->location;
-	}
-};
-
-template<typename node_t>
-struct __GetCL<node_t, false> {
-	static inline CodeLocation * get( node_t const * ) {
-		return nullptr;
-	}
-};
-
-template<typename node_t>
-CodeLocation const * get_code_location( node_t const * node ) {
-	return __GetCL< node_t, has_code_location< node_t >::value >::get( node );
-}
-
-template<typename node_t>
-CodeLocation * get_code_location( node_t * node ) {
-	return __GetCL< node_t, has_code_location< node_t >::value >::get( node );
-}
-
 // Fill every location with a nearby (parent) location.
 class FillCore : public ast::WithGuards {
 	CodeLocation const * parent;
+
+	template<typename node_t>
+	node_t const * parse_visit( node_t const * node ) {
+		if ( node->location.isUnset() ) {
+			assert( parent );
+			node_t * newNode = ast::mutate( node );
+			newNode->location = *parent;
+			return newNode;
+		}
+		GuardValue( parent ) = &node->location;
+		return node;
+	}
+
+	bool hasUnsetLabels( const ast::Stmt * stmt ) {
+		for ( const ast::Label& label : stmt->labels ) {
+			if ( label.location.isUnset() ) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	template<typename node_t>
+	node_t const * stmt_visit( node_t const * node ) {
+		assert( node->location.isSet() );
+
+		if ( hasUnsetLabels( node ) ) {
+			node_t * newNode = ast::mutate( node );
+			for ( ast::Label& label : newNode->labels ) {
+				if ( label.location.isUnset() ) {
+					label.location = newNode->location;
+				}
+			}
+			return newNode;
+		}
+		return node;
+	}
+
+	template<typename node_t>
+	auto visit( node_t const * node, long ) {
+		return node;
+	}
+
+	template<typename node_t>
+	auto visit( node_t const * node, int ) -> typename
+			std::remove_reference< decltype( node->location, node ) >::type {
+		return parse_visit( node );
+	}
+
+	template<typename node_t>
+	auto visit( node_t const * node, char ) -> typename
+			std::remove_reference< decltype( node->labels, node ) >::type {
+		return stmt_visit( parse_visit( node ) );
+	}
+
 public:
 	FillCore() : parent( nullptr ) {}
+	FillCore( const CodeLocation& location ) : parent( &location ) {
+		assert( location.isSet() );
+	}
 
 	template<typename node_t>
 	node_t const * previsit( node_t const * node ) {
-		GuardValue( parent );
-		CodeLocation const * location = get_code_location( node );
-		if ( location && location->isUnset() ) {
-			assert( parent );
-			node_t * newNode = ast::mutate( node );
-			CodeLocation * newLocation = get_code_location( newNode );
-			assert( newLocation );
-			*newLocation = *parent;
-			parent = newLocation;
-			return newNode;
-		} else if ( location ) {
-			parent = location;
-		}
-		return node;
+		return visit( node, '\0' );
 	}
 };
@@ -233,29 +240,7 @@
 
 	template<typename node_t>
-	void previsit( node_t const * node ) {
-		CodeLocation const * location = get_code_location( node );
-		if ( location && location->isUnset() ) {
+	auto previsit( node_t const * node ) -> decltype( node->location, void() ) {
+		if ( node->location.isUnset() ) {
 			unset.push_back( node );
-		}
-	}
-};
-
-class LocalFillCore : public ast::WithGuards {
-	CodeLocation const * parent;
-public:
-	LocalFillCore( CodeLocation const & location ) : parent( &location ) {
-		assert( location.isSet() );
-	}
-
-	template<typename node_t>
-	auto previsit( node_t const * node )
-			-> typename std::enable_if<has_code_location<node_t>::value, node_t const *>::type {
-		if ( node->location.isSet() ) {
-			GuardValue( parent ) = &node->location;
-			return node;
-		} else {
-			node_t * mut = ast::mutate( node );
-			mut->location = *parent;
-			return mut;
 		}
 	}
@@ -304,5 +289,5 @@
 ast::Node const * localFillCodeLocations(
 		CodeLocation const & location , ast::Node const * node ) {
-	ast::Pass<LocalFillCore> visitor( location );
+	ast::Pass<FillCore> visitor( location );
 	return node->accept( visitor );
 }
Index: src/ControlStruct/LabelGeneratorNew.hpp
===================================================================
--- src/ControlStruct/LabelGeneratorNew.hpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/ControlStruct/LabelGeneratorNew.hpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -18,5 +18,5 @@
 #include <string>										// for string
 
-class CodeLocation;
+struct CodeLocation;
 
 namespace ast {
Index: src/ControlStruct/MultiLevelExit.cpp
===================================================================
--- src/ControlStruct/MultiLevelExit.cpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/ControlStruct/MultiLevelExit.cpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -18,4 +18,5 @@
 #include "AST/Pass.hpp"
 #include "AST/Stmt.hpp"
+#include "Common/CodeLocationTools.hpp"
 #include "LabelGeneratorNew.hpp"
 
@@ -228,77 +229,77 @@
 	// Labels on different stmts require different approaches to access
 	switch ( stmt->kind ) {
-	  case BranchStmt::Goto:
+	case BranchStmt::Goto:
 		return stmt;
-	  case BranchStmt::Continue:
-	  case BranchStmt::Break: {
-		  bool isContinue = stmt->kind == BranchStmt::Continue;
-		  // Handle unlabeled break and continue.
-		  if ( stmt->target.empty() ) {
-			  if ( isContinue ) {
-				  targetEntry = findEnclosingControlStructure( isContinueTarget );
-			  } else {
-				  if ( enclosing_control_structures.empty() ) {
+	case BranchStmt::Continue:
+	case BranchStmt::Break: {
+		bool isContinue = stmt->kind == BranchStmt::Continue;
+		// Handle unlabeled break and continue.
+		if ( stmt->target.empty() ) {
+			if ( isContinue ) {
+				targetEntry = findEnclosingControlStructure( isContinueTarget );
+			} else {
+				if ( enclosing_control_structures.empty() ) {
 					  SemanticError( stmt->location,
 									 "'break' outside a loop, 'switch', or labelled block" );
-				  }
-				  targetEntry = findEnclosingControlStructure( isBreakTarget );
-			  }
-			  // Handle labeled break and continue.
-		  } else {
-			  // Lookup label in table to find attached control structure.
-			  targetEntry = findEnclosingControlStructure(
-				  [ targetStmt = target_table.at(stmt->target) ](auto entry){
+				}
+				targetEntry = findEnclosingControlStructure( isBreakTarget );
+			}
+			// Handle labeled break and continue.
+		} else {
+			// Lookup label in table to find attached control structure.
+			targetEntry = findEnclosingControlStructure(
+				[ targetStmt = target_table.at(stmt->target) ](auto entry){
 					  return entry.stmt == targetStmt;
-				  } );
-		  }
-		  // Ensure that selected target is valid.
-		  if ( targetEntry == enclosing_control_structures.rend() || ( isContinue && ! isContinueTarget( *targetEntry ) ) ) {
-			  SemanticError( stmt->location, toString( (isContinue ? "'continue'" : "'break'"),
+				} );
+		}
+		// Ensure that selected target is valid.
+		if ( targetEntry == enclosing_control_structures.rend() || ( isContinue && ! isContinueTarget( *targetEntry ) ) ) {
+			SemanticError( stmt->location, toString( (isContinue ? "'continue'" : "'break'"),
 							" target must be an enclosing ", (isContinue ? "loop: " : "control structure: "),
 							stmt->originalTarget ) );
-		  }
-		  break;
-	  }
-	  // handle fallthrough in case/switch stmts
-	  case BranchStmt::FallThrough: {
-		  targetEntry = findEnclosingControlStructure( isFallthroughTarget );
-		  // Check that target is valid.
-		  if ( targetEntry == enclosing_control_structures.rend() ) {
-			  SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
-		  }
-		  if ( ! stmt->target.empty() ) {
-			  // Labelled fallthrough: target must be a valid fallthough label.
-			  if ( ! fallthrough_labels.count( stmt->target ) ) {
-				  SemanticError( stmt->location, toString( "'fallthrough' target must be a later case statement: ",
+		}
+		break;
+	}
+	// handle fallthrough in case/switch stmts
+	case BranchStmt::FallThrough: {
+		targetEntry = findEnclosingControlStructure( isFallthroughTarget );
+		// Check that target is valid.
+		if ( targetEntry == enclosing_control_structures.rend() ) {
+			SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
+		}
+		if ( ! stmt->target.empty() ) {
+			// Labelled fallthrough: target must be a valid fallthough label.
+			if ( ! fallthrough_labels.count( stmt->target ) ) {
+				SemanticError( stmt->location, toString( "'fallthrough' target must be a later case statement: ",
 														   stmt->originalTarget ) );
-			  }
-			  return new BranchStmt( stmt->location, BranchStmt::Goto, stmt->originalTarget );
-		  }
-		  break;
-	  }
-	  case BranchStmt::FallThroughDefault: {
-		  targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget );
-
-		  // Check if in switch or choose statement.
-		  if ( targetEntry == enclosing_control_structures.rend() ) {
-			  SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
-		  }
-
-		  // Check if switch or choose has default clause.
-		  auto switchStmt = strict_dynamic_cast< const SwitchStmt * >( targetEntry->stmt );
-		  bool foundDefault = false;
-		  for ( auto caseStmt : switchStmt->cases ) {
-			  if ( caseStmt->isDefault() ) {
-				  foundDefault = true;
-				  break;
-			  }
-		  }
-		  if ( ! foundDefault ) {
-			  SemanticError( stmt->location, "'fallthrough default' must be enclosed in a 'switch' or 'choose'"
-							 "control structure with a 'default' clause" );
-		  }
-		  break;
-	  }
-	  default:
+			}
+			return new BranchStmt( stmt->location, BranchStmt::Goto, stmt->originalTarget );
+		}
+		break;
+	}
+	case BranchStmt::FallThroughDefault: {
+		targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget );
+
+		// Check if in switch or choose statement.
+		if ( targetEntry == enclosing_control_structures.rend() ) {
+			SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
+		}
+
+		// Check if switch or choose has default clause.
+		auto switchStmt = strict_dynamic_cast< const SwitchStmt * >( targetEntry->stmt );
+		bool foundDefault = false;
+		for ( auto caseStmt : switchStmt->cases ) {
+			if ( caseStmt->isDefault() ) {
+				foundDefault = true;
+				break;
+			}
+		}
+		if ( ! foundDefault ) {
+			SemanticError( stmt->location, "'fallthrough default' must be enclosed in a 'switch' or 'choose'"
+						   "control structure with a 'default' clause" );
+		}
+		break;
+	}
+	default:
 		assert( false );
 	}
@@ -307,17 +308,17 @@
 	Label exitLabel( CodeLocation(), "" );
 	switch ( stmt->kind ) {
-	  case BranchStmt::Break:
+	case BranchStmt::Break:
 		assert( ! targetEntry->useBreakExit().empty() );
 		exitLabel = targetEntry->useBreakExit();
 		break;
-	  case BranchStmt::Continue:
+	case BranchStmt::Continue:
 		assert( ! targetEntry->useContExit().empty() );
 		exitLabel = targetEntry->useContExit();
 		break;
-	  case BranchStmt::FallThrough:
+	case BranchStmt::FallThrough:
 		assert( ! targetEntry->useFallExit().empty() );
 		exitLabel = targetEntry->useFallExit();
 		break;
-	  case BranchStmt::FallThroughDefault:
+	case BranchStmt::FallThroughDefault:
 		assert( ! targetEntry->useFallDefaultExit().empty() );
 		exitLabel = targetEntry->useFallDefaultExit();
@@ -327,5 +328,5 @@
 		}
 		break;
-	  default:
+	default:
 		assert(0);
 	}
@@ -633,5 +634,7 @@
 	Pass<MultiLevelExitCore> visitor( labelTable );
 	const CompoundStmt * ret = stmt->accept( visitor );
-	return ret;
+	// There are some unset code locations slipping in, possibly by Labels.
+	const Node * node = localFillCodeLocations( ret->location, ret );
+	return strict_dynamic_cast<const CompoundStmt *>( node );
 }
 } // namespace ControlStruct
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/Parser/parser.yy	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed May  4 14:25:20 2022
-// Update Count     : 5277
+// Last Modified On : Wed May  4 17:22:48 2022
+// Update Count     : 5279
 //
 
@@ -1224,5 +1224,8 @@
 		{ $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); }
 	| WHILE '(' ')' statement ELSE statement			// CFA
-		{ $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); SemanticWarning( yylloc, Warning::SuperfluousElse ); }
+		{
+			$$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) );
+			SemanticWarning( yylloc, Warning::SuperfluousElse );
+		}
 	| WHILE '(' conditional_declaration ')' statement	%prec THEN
 		{ $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); }
@@ -1232,13 +1235,19 @@
 		{ $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); }
 	| DO statement WHILE '(' ')' ELSE statement			// CFA
-		{ $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); SemanticWarning( yylloc, Warning::SuperfluousElse ); }
-	| DO statement WHILE '(' comma_expression ')' ';'	%prec THEN
+		{
+			$$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) );
+			SemanticWarning( yylloc, Warning::SuperfluousElse );
+		}
+	| DO statement WHILE '(' comma_expression ')' ';'
 		{ $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); }
 	| DO statement WHILE '(' comma_expression ')' ELSE statement // CFA
 		{ $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); }
-	| FOR '(' ')' statement								// CFA => for ( ;; )
+	| FOR '(' ')' statement								%prec THEN // CFA => for ( ;; )
 		{ $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); }
-	| FOR '(' ')' statement ELSE statement			// CFA
-		{ $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); SemanticWarning( yylloc, Warning::SuperfluousElse ); }
+	| FOR '(' ')' statement ELSE statement				// CFA
+		{
+			$$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) );
+			SemanticWarning( yylloc, Warning::SuperfluousElse );
+		}
 	| FOR '(' for_control_expression_list ')' statement	%prec THEN
 	  	{ $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); }
Index: src/Validate/Autogen.cpp
===================================================================
--- src/Validate/Autogen.cpp	(revision f75e25bacd14e7d28dac1228e86806938c10a4a1)
+++ src/Validate/Autogen.cpp	(revision 015925aa27a2898e2c8dc848bc56a9000843accf)
@@ -350,4 +350,5 @@
 		name,
 		std::move( type_params ),
+		std::move( assertions ),
 		std::move( params ),
 		std::move( returns ),
@@ -360,5 +361,4 @@
 		// Auto-generated routines are inline to avoid conflicts.
 		ast::Function::Specs( ast::Function::Inline ) );
-	decl->assertions = std::move( assertions );
 	decl->fixUniqueId();
 	return decl;
