Index: src/CodeGen/FixMain.cc
===================================================================
--- src/CodeGen/FixMain.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/CodeGen/FixMain.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -39,5 +39,5 @@
 	{
 		if(main_signature) {
-			throw SemanticError("Multiple definition of main routine\n", functionDecl);
+			throw SemanticError(functionDecl, "Multiple definition of main routine\n");
 		}
 		main_signature.reset( functionDecl->clone() );
Index: src/CodeGen/FixNames.cc
===================================================================
--- src/CodeGen/FixNames.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/CodeGen/FixNames.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -118,5 +118,5 @@
 			int nargs = functionDecl->get_functionType()->get_parameters().size();
 			if( !(nargs == 0 || nargs == 2 || nargs == 3) ) {
-				throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", functionDecl);
+				throw SemanticError(functionDecl, "Main expected to have 0, 2 or 3 arguments\n");
 			}
 			functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( new ConstantExpr( Constant::from_int( 0 ) ) ) );
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Common/PassVisitor.impl.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -77,5 +77,4 @@
 			maybeAccept_impl( *i, visitor );
 		} catch( SemanticError &e ) {
-			e.set_location( (*i)->location );
 			errors.append( e );
 		}
@@ -104,5 +103,4 @@
 			maybeMutate_impl( *i, mutator );
 		} catch( SemanticError &e ) {
-			e.set_location( (*i)->location );
 			errors.append( e );
 		}
@@ -134,5 +132,4 @@
 			}
 		} catch( SemanticError &e ) {
-			e.set_location( (*i)->location );
 			errors.append( e );
 		}
@@ -163,5 +160,4 @@
 			} // if
 		} catch( SemanticError &e ) {
-			e.set_location( (*i)->location );
 			errors.append( e );
 		} // try
@@ -200,5 +196,4 @@
 
 		} catch ( SemanticError &e ) {
-			e.set_location( (*i)->location );
 			errors.append( e );
 		}
Index: src/Common/SemanticError.cc
===================================================================
--- src/Common/SemanticError.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Common/SemanticError.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -23,9 +23,6 @@
 #include "SemanticError.h"
 
-SemanticError::SemanticError() {
-}
-
-SemanticError::SemanticError( std::string error ) {
-	append( error );
+SemanticError::SemanticError( CodeLocation location, std::string error ) {
+	append( location, error );
 }
 
@@ -34,6 +31,6 @@
 }
 
-void SemanticError::append( const std::string & msg ) {
-	errors.emplace_back( error_str() + msg );
+void SemanticError::append( CodeLocation location, const std::string & msg ) {
+	errors.emplace_back( location, msg );
 }
 
@@ -42,13 +39,13 @@
 }
 
-void SemanticError::print( std::ostream &os ) {
+void SemanticError::print() {
 	using std::to_string;
 	for( auto err : errors ) {
-		os << err.location << err.description << std::endl;
+		std::cerr << bold() << err.location << error_str() << reset_font() << err.description << std::endl;
 	}
 }
 
-void SemanticError::set_location( const CodeLocation& location ) {
-	errors.begin()->maybeSet( location );
+SemanticWarning::SemanticWarning( CodeLocation location, std::string msg ) {
+	std::cerr << bold() << location << warning_str() << reset_font() << msg << std::endl;
 }
 
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Common/SemanticError.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -24,24 +24,23 @@
 #include "CodeLocation.h"								// for CodeLocation, toString
 
+//-----------------------------------------------------------------------------
+// Errors
 struct error {
+	CodeLocation location;
 	std::string description;
-	CodeLocation location;
 
 	error() = default;
-	error( const std::string & str ) : description( str ) {}
-
-	void maybeSet( const CodeLocation & location ) {
-		if( this->location.isUnset() ) {
-			this->location = location;
-		}
-	}
+	error( CodeLocation loc, const std::string & str ) : location( loc ), description( str ) {}
 };
 
 class SemanticError : public std::exception {
   public:
-	SemanticError();
-	SemanticError( std::string error );
-	template< typename T > SemanticError( const std::string & error, const T * obj );
+  	SemanticError() = default;
+	SemanticError( CodeLocation location, std::string error );
 	~SemanticError() throw() {}
+
+	// constructs an exception using the given message and the printed representation of the obj (T must have a print method)
+	template< typename T > SemanticError(const T * obj, const std::string & error);
+	template< typename T > SemanticError( CodeLocation location, const T * obj, const std::string & error);
 
 	static inline const std::string & error_str() {
@@ -51,11 +50,7 @@
 
 	void append( SemanticError & other );
-	void append( const std::string & );
+	void append( CodeLocation location, const std::string & );
 	bool isEmpty() const;
-	void print( std::ostream & os );
-
-	void set_location( const CodeLocation & location );
-	// constructs an exception using the given message and the printed representation of the obj (T must have a print
-	// method)
+	void print();
   private:
 	std::list< error > errors;
@@ -63,6 +58,68 @@
 
 template< typename T >
-SemanticError::SemanticError( const std::string & error, const T * obj ) {
-	append( toString( error, obj ) );
+SemanticError::SemanticError( const T * obj, const std::string & error )
+	: SemanticError( obj->location, toString( error, obj ) )
+{}
+
+template< typename T >
+SemanticError::SemanticError( CodeLocation location, const T * obj, const std::string & error )
+	: SemanticError( location, toString( error, obj ) )
+{}
+
+//-----------------------------------------------------------------------------
+// Warnings
+class SemanticWarning {
+  public:
+  	SemanticWarning( CodeLocation location, std::string error );
+	~SemanticWarning() throw() {}
+
+	// constructs an exception using the given message and the printed representation of the obj (T must have a print method)
+	template< typename T > SemanticWarning(const T * obj, const std::string & error);
+	template< typename T > SemanticWarning( CodeLocation location, const T * obj, const std::string & error);
+
+	static inline const std::string & warning_str() {
+		static std::string str = isatty( STDERR_FILENO ) ? "\e[95mwarning:\e[39m " : "warning: ";
+		return str;
+	}
+
+  private:
+};
+
+template< typename T >
+SemanticWarning::SemanticWarning( const T * obj, const std::string & error )
+	: SemanticWarning( obj->location, toString( error, obj ) )
+{}
+
+template< typename T >
+SemanticWarning::SemanticWarning( CodeLocation location, const T * obj, const std::string & error )
+	: SemanticWarning( location, toString( error, obj ) )
+{}
+
+//-----------------------------------------------------------------------------
+// Helpers
+static inline const std::string & bold_ttycode() {
+	static std::string str = isatty( STDERR_FILENO ) ? "\e[1m" : "";
+	return str;
+}
+
+static inline const std::string & reset_font_ttycode() {
+	static std::string str = isatty( STDERR_FILENO ) ? "\e[0m" : "";
+	return str;
+}
+
+static inline std::string make_bold( const std::string & str ) {
+	return bold_ttycode() + str + reset_font_ttycode();
+}
+
+struct bold {};
+static inline std::ostream & operator<<(std::ostream & os, bold) {
+	os << bold_ttycode();
+	return os;
+}
+
+struct reset_font {};
+static inline std::ostream & operator<<(std::ostream & os, reset_font) {
+	os << reset_font_ttycode();
+	return os;
 }
 
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Concurrency/Keywords.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -276,5 +276,4 @@
 			handle( decl );
 		}
-
 	}
 
@@ -282,5 +281,5 @@
 		if( ! decl->body ) return;
 
-		if( !type_decl ) throw SemanticError( context_error, decl );
+		if( !type_decl ) throw SemanticError( decl, context_error );
 
 		FunctionDecl * func = forwardDeclare( decl );
@@ -419,9 +418,9 @@
 		if( mutexArgs.empty() ) return;
 
-		if( CodeGen::isConstructor(decl->name) ) throw SemanticError( "constructors cannot have mutex parameters", decl );
+		if( CodeGen::isConstructor(decl->name) ) throw SemanticError( decl, "constructors cannot have mutex parameters" );
 
 		bool isDtor = CodeGen::isDestructor( decl->name );
 
-		if( isDtor && mutexArgs.size() != 1 ) throw SemanticError( "destructors can only have 1 mutex argument", decl );
+		if( isDtor && mutexArgs.size() != 1 ) throw SemanticError( decl, "destructors can only have 1 mutex argument" );
 
 		for(auto arg : mutexArgs) {
@@ -432,7 +431,7 @@
 		if( ! body ) return;
 
-		if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
-		if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
-		if( !dtor_guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
+		if( !monitor_decl ) throw SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor>" );
+		if( !guard_decl ) throw SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor>" );
+		if( !dtor_guard_decl ) throw SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor>" );
 
 		if( isDtor ) {
@@ -480,13 +479,13 @@
 		//Makes sure it's not a copy
 		ReferenceType* rty = dynamic_cast< ReferenceType * >( ty );
-		if( ! rty ) throw SemanticError( "Mutex argument must be of reference type ", arg );
+		if( ! rty ) throw SemanticError( arg, "Mutex argument must be of reference type " );
 
 		//Make sure the we are pointing directly to a type
 		Type* base = rty->get_base();
-		if( dynamic_cast< ReferenceType * >( base ) ) throw SemanticError( "Mutex argument have exactly one level of indirection ", arg );
-		if( dynamic_cast< PointerType * >( base ) ) throw SemanticError( "Mutex argument have exactly one level of indirection ", arg );
+		if( dynamic_cast< ReferenceType * >( base ) ) throw SemanticError( arg, "Mutex argument have exactly one level of indirection " );
+		if( dynamic_cast< PointerType * >( base ) ) throw SemanticError( arg, "Mutex argument have exactly one level of indirection " );
 
 		//Make sure that typed isn't mutex
-		if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
+		if( base->get_mutex() ) throw SemanticError( arg, "mutex keyword may only appear once per argument " );
 	}
 
@@ -626,5 +625,5 @@
 		if( type && type->get_baseStruct()->is_thread() ) {
 			if( !thread_decl || !thread_ctor_seen ) {
-				throw SemanticError("thread keyword requires threads to be in scope, add #include <thread>");
+				throw SemanticError( type->get_baseStruct()->location, "thread keyword requires threads to be in scope, add #include <thread>");
 			}
 
Index: src/Concurrency/Waitfor.cc
===================================================================
--- src/Concurrency/Waitfor.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Concurrency/Waitfor.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -249,5 +249,6 @@
 
 	Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) {
-		if( !decl_monitor || !decl_acceptable || !decl_mask ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
+		if( !decl_monitor || !decl_acceptable || !decl_mask )
+			throw SemanticError( waitfor, "waitfor keyword requires monitors to be in scope, add #include <monitor>" );
 
 		CompoundStmt * stmt = new CompoundStmt();
Index: src/ControlStruct/ExceptTranslate.cc
===================================================================
--- src/ControlStruct/ExceptTranslate.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/ControlStruct/ExceptTranslate.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -572,7 +572,7 @@
 			// Pass.
 		} else if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
-			throw SemanticError("catch must have exception type");
+			throw SemanticError(catchStmt->location, "catch must have exception type");
 		} else {
-			throw SemanticError("catchResume must have exception type");
+			throw SemanticError(catchStmt->location, "catchResume must have exception type");
 		}
 
Index: src/ControlStruct/LabelFixer.cc
===================================================================
--- src/ControlStruct/LabelFixer.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/ControlStruct/LabelFixer.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -92,5 +92,5 @@
 			} else if ( labelTable[ l ]->defined() ) {
 				// defined twice, error
-				throw SemanticError( "Duplicate definition of label: " + l.get_name() );
+				throw SemanticError( l.get_statement()->location, "Duplicate definition of label: " + l.get_name() );
 			}	else {
 				// used previously, but undefined until now -> link with this entry
@@ -121,5 +121,5 @@
 		for ( std::map< Label, Entry * >::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
 			if ( ! i->second->defined() ) {
-				throw SemanticError( "Use of undefined label: " + i->first.get_name() );
+				throw SemanticError( i->first.get_statement()->location, "Use of undefined label: " + i->first.get_name() );
 			}
 			(*ret)[ i->first ] = i->second->get_definition();
Index: src/ControlStruct/MLEMutator.cc
===================================================================
--- src/ControlStruct/MLEMutator.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/ControlStruct/MLEMutator.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -115,5 +115,5 @@
 					} else {
 						// break target is outmost control structure
-						if ( enclosingControlStructures.empty() ) throw SemanticError( "'break' outside a loop, switch, or labelled block" );
+						if ( enclosingControlStructures.empty() ) throw SemanticError( branchStmt->location, "'break' outside a loop, switch, or labelled block" );
 						targetEntry = enclosingControlStructures.rbegin();
 					} // if
@@ -124,5 +124,5 @@
 				// ensure that selected target is valid
 				if ( targetEntry == enclosingControlStructures.rend() || (isContinue && ! isLoop( targetEntry->get_controlStructure() ) ) ) {
-					throw SemanticError( toString( (isContinue ? "'continue'" : "'break'"), " target must be an enclosing ", (isContinue ? "loop: " : "control structure: "), originalTarget ) );
+					throw SemanticError( branchStmt->location, toString( (isContinue ? "'continue'" : "'break'"), " target must be an enclosing ", (isContinue ? "loop: " : "control structure: "), originalTarget ) );
 				} // if
 				break;
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/GenPoly/Box.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -229,5 +229,4 @@
 				} // if
 			} catch( SemanticError &e ) {
-				e.set_location( (*i)->location );
 				errors.append( e );
 			} // try
@@ -576,5 +575,5 @@
 						}
 					} else {
-						throw SemanticError( "Cannot pass non-struct type for generic struct: ", argBaseType );
+						throw SemanticError( argBaseType, "Cannot pass non-struct type for generic struct: " );
 					}
 				}
@@ -598,5 +597,5 @@
 					} else {
 						// xxx - should this be an assertion?
-						throw SemanticError( toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ), appExpr );
+						throw SemanticError( appExpr, toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ) );
 					} // if
 				} // if
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/InitTweak/FixInit.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -282,5 +282,4 @@
 					translationUnit.splice( i, fixer.pass.staticDtorDecls );
 				} catch( SemanticError &e ) {
-					e.set_location( (*i)->location );
 					errors.append( e );
 				} // try
@@ -895,5 +894,5 @@
 			)
 			if ( ! diff.empty() ) {
-				throw SemanticError( std::string("jump to label '") + stmt->get_target().get_name() + "' crosses initialization of " + (*diff.begin())->get_name() + " ", stmt );
+				throw SemanticError( stmt, std::string("jump to label '") + stmt->get_target().get_name() + "' crosses initialization of " + (*diff.begin())->get_name() + " " );
 			} // if
 			// S_G-S_L results in set of objects that must be destructed
@@ -1111,6 +1110,5 @@
 		template< typename Visitor, typename... Params >
 		void error( Visitor & v, CodeLocation loc, const Params &... params ) {
-			SemanticError err( toString( params... ) );
-			err.set_location( loc );
+			SemanticError err( loc, toString( params... ) );
 			v.errors.append( err );
 		}
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/InitTweak/GenInit.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -317,7 +317,7 @@
 		if ( tryConstruct( objDecl ) && ( managedTypes.isManaged( objDecl ) || ((! inFunction || objDecl->get_storageClasses().is_static ) && ! isConstExpr( objDecl->get_init() ) ) ) ) {
 			// constructed objects cannot be designated
-			if ( isDesignated( objDecl->get_init() ) ) throw SemanticError( "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n", objDecl );
+			if ( isDesignated( objDecl->get_init() ) ) throw SemanticError( objDecl, "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n" );
 			// constructed objects should not have initializers nested too deeply
-			if ( ! checkInitDepth( objDecl ) ) throw SemanticError( "Managed object's initializer is too deep ", objDecl );
+			if ( ! checkInitDepth( objDecl ) ) throw SemanticError( objDecl, "Managed object's initializer is too deep " );
 
 			objDecl->set_init( genCtorInit( objDecl ) );
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/InitTweak/InitTweak.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -225,5 +225,5 @@
 					// xxx - this shouldn't be an error, but need a way to
 					// terminate without creating output, so should catch this error
-					throw SemanticError( "unbalanced list initializers" );
+					throw SemanticError( init->location, "unbalanced list initializers" );
 				}
 
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Parser/DeclarationNode.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -581,15 +581,15 @@
 					dst->basictype = src->basictype;
 				} else if ( src->basictype != DeclarationNode::NoBasicType )
-					throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::basicTypeNames[ src->basictype ] + " in type: ", src );
+					throw SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::basicTypeNames[ src->basictype ] + " in type: " );
 
 				if ( dst->complextype == DeclarationNode::NoComplexType ) {
 					dst->complextype = src->complextype;
 				} else if ( src->complextype != DeclarationNode::NoComplexType )
-					throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::complexTypeNames[ src->complextype ] + " in type: ", src );
+					throw SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::complexTypeNames[ src->complextype ] + " in type: " );
 
 				if ( dst->signedness == DeclarationNode::NoSignedness ) {
 					dst->signedness = src->signedness;
 				} else if ( src->signedness != DeclarationNode::NoSignedness )
-					throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::signednessNames[ src->signedness ] + " in type: ", src );
+					throw SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::signednessNames[ src->signedness ] + " in type: " );
 
 				if ( dst->length == DeclarationNode::NoLength ) {
@@ -598,5 +598,5 @@
 					dst->length = DeclarationNode::LongLong;
 				} else if ( src->length != DeclarationNode::NoLength )
-					throw SemanticError( string( "conflicting type specifier " ) + DeclarationNode::lengthNames[ src->length ] + " in type: ", src );
+					throw SemanticError( yylloc, src, string( "conflicting type specifier " ) + DeclarationNode::lengthNames[ src->length ] + " in type: " );
 			} // if
 			break;
@@ -966,5 +966,4 @@
 			} // if
 		} catch( SemanticError &e ) {
-			e.set_location( cur->location );
 			errors.append( e );
 		} // try
@@ -1001,5 +1000,4 @@
 			} // if
 		} catch( SemanticError &e ) {
-			e.set_location( cur->location );
 			errors.append( e );
 		} // try
@@ -1020,5 +1018,4 @@
 			* out++ = cur->buildType();
 		} catch( SemanticError &e ) {
-			e.set_location( cur->location );
 			errors.append( e );
 		} // try
@@ -1032,5 +1029,5 @@
 
 Declaration * DeclarationNode::build() const {
-	if ( ! error.empty() ) throw SemanticError( error + " in declaration of ", this );
+	if ( ! error.empty() ) throw SemanticError( this, error + " in declaration of " );
 
 	if ( asmStmt ) {
@@ -1055,5 +1052,5 @@
 		//    inline _Noreturn int i;			// disallowed
 		if ( type->kind != TypeData::Function && funcSpecs.any() ) {
-			throw SemanticError( "invalid function specifier for ", this );
+			throw SemanticError( this, "invalid function specifier for " );
 		} // if
 		return buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
@@ -1065,5 +1062,5 @@
 	//    inlne _Noreturn enum   E { ... };		// disallowed
 	if ( funcSpecs.any() ) {
-		throw SemanticError( "invalid function specifier for ", this );
+		throw SemanticError( this, "invalid function specifier for " );
 	} // if
 	assertf( name, "ObjectDecl must a have name\n" );
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Parser/ExpressionNode.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -356,5 +356,5 @@
 
 Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
-	if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
+	if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( yylloc, "invalid tuple index " + str );
 	Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
 	delete &str;
@@ -363,5 +363,5 @@
 
 Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
-	if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
+	if ( str[str.size()-1] != '.' ) throw SemanticError( yylloc, "invalid tuple index " + str );
 	Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
 	delete &str;
Index: src/Parser/LinkageSpec.cc
===================================================================
--- src/Parser/LinkageSpec.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Parser/LinkageSpec.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -24,5 +24,5 @@
 namespace LinkageSpec {
 
-Spec linkageCheck( const string * spec ) {
+Spec linkageCheck( CodeLocation location, const string * spec ) {
 	assert( spec );
 	unique_ptr<const string> guard( spec );	// allocated by lexer
@@ -34,9 +34,9 @@
 		return BuiltinC;
 	} else {
-		throw SemanticError( "Invalid linkage specifier " + *spec );
+		throw SemanticError( location, "Invalid linkage specifier " + *spec );
 	} // if
 }
 
-Spec linkageUpdate( Spec old_spec, const string * cmd ) {
+Spec linkageUpdate( CodeLocation location, Spec old_spec, const string * cmd ) {
 	assert( cmd );
 	unique_ptr<const string> guard( cmd ); // allocated by lexer
@@ -48,5 +48,5 @@
 		return old_spec;
 	} else {
-		throw SemanticError( "Invalid linkage specifier " + *cmd );
+		throw SemanticError( location, "Invalid linkage specifier " + *cmd );
 	} // if
 }
Index: src/Parser/LinkageSpec.h
===================================================================
--- src/Parser/LinkageSpec.h	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Parser/LinkageSpec.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -17,4 +17,6 @@
 
 #include <string>
+
+#include "Common/CodeLocation.h"
 
 namespace LinkageSpec {
@@ -45,7 +47,7 @@
 
 
-	Spec linkageCheck( const std::string * );
+	Spec linkageCheck( CodeLocation location, const std::string * );
 	// Returns the Spec with the given name (limited to C, Cforall & BuiltinC)
-	Spec linkageUpdate( Spec old_spec, const std::string * cmd );
+	Spec linkageUpdate( CodeLocation location, Spec old_spec, const std::string * cmd );
 	/* If cmd = "C" returns a Spec that is old_spec with is_mangled = false
 	 * If cmd = "Cforall" returns old_spec Spec with is_mangled = true
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Parser/ParseNode.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -434,5 +434,4 @@
 			} // if
 		} catch( SemanticError &e ) {
-			e.set_location( cur->location );
 			errors.append( e );
 		} // try
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Parser/TypeData.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -31,5 +31,5 @@
 using namespace std;
 
-TypeData::TypeData( Kind k ) : kind( k ), base( nullptr ), forall( nullptr ) /*, PTR1( (void*)(0xdeadbeefdeadbeef)), PTR2( (void*)(0xdeadbeefdeadbeef) ) */ {
+TypeData::TypeData( Kind k ) : location( yylloc ), kind( k ), base( nullptr ), forall( nullptr ) /*, PTR1( (void*)(0xdeadbeefdeadbeef)), PTR2( (void*)(0xdeadbeefdeadbeef) ) */ {
 	switch ( kind ) {
 	  case Unknown:
@@ -521,5 +521,5 @@
 
 static string genTSError( string msg, DeclarationNode::BasicType basictype ) {
-	throw SemanticError( string( "invalid type specifier \"" ) + msg + "\" for type \"" + DeclarationNode::basicTypeNames[basictype] + "\"." );
+	throw SemanticError( yylloc, string( "invalid type specifier \"" ) + msg + "\" for type \"" + DeclarationNode::basicTypeNames[basictype] + "\"." );
 } // genTSError
 
@@ -800,5 +800,5 @@
 	assert( td->base );
 	if ( td->symbolic.isTypedef ) {
-		ret = new TypedefDecl( name, scs, typebuild( td->base ), linkage );
+		ret = new TypedefDecl( name, td->location, scs, typebuild( td->base ), linkage );
 	} else {
 		ret = new TypeDecl( name, scs, typebuild( td->base ), TypeDecl::Dtype, true );
@@ -923,8 +923,8 @@
 				// type set => parameter name already transformed by a declaration names so there is a duplicate
 				// declaration name attempting a second transformation
-				if ( param->type ) throw SemanticError( string( "duplicate declaration name " ) + *param->name );
+				if ( param->type ) throw SemanticError( param->location, string( "duplicate declaration name " ) + *param->name );
 				// declaration type reset => declaration already transformed by a parameter name so there is a duplicate
 				// parameter name attempting a second transformation
-				if ( ! decl->type ) throw SemanticError( string( "duplicate parameter name " ) + *param->name );
+				if ( ! decl->type ) throw SemanticError( param->location, string( "duplicate parameter name " ) + *param->name );
 				param->type = decl->type;				// set copy declaration type to parameter type
 				decl->type = nullptr;					// reset declaration type
@@ -933,5 +933,5 @@
 		} // for
 		// declaration type still set => type not moved to a matching parameter so there is a missing parameter name
-		if ( decl->type ) throw SemanticError( string( "missing name in parameter list " ) + *decl->name );
+		if ( decl->type ) throw SemanticError( decl->location, string( "missing name in parameter list " ) + *decl->name );
 	} // for
 
Index: src/Parser/TypeData.h
===================================================================
--- src/Parser/TypeData.h	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Parser/TypeData.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -76,4 +76,6 @@
 	};
 
+	CodeLocation location;
+
 	Kind kind;
 	TypeData * base;
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/Parser/parser.yy	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Dec 21 11:32:56 2017
-// Update Count     : 2996
+// Last Modified On : Thu Feb 15 17:12:31 2018
+// Update Count     : 3006
 //
 
@@ -482,7 +482,19 @@
 		{ $$ = new ExpressionNode( new StmtExpr( dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >($2) ) ) ); }
 	| type_name '.' no_attr_identifier					// CFA, nested type
-		{ throw SemanticError("Qualified names are currently unimplemented."); $$ = nullptr; }								// FIX ME
+		{ throw SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } // FIX ME
 	| type_name '.' '[' push field_list pop ']'			// CFA, nested type / tuple field selector
-		{ throw SemanticError("Qualified names are currently unimplemented."); $$ = nullptr; }								// FIX ME
+		{ throw SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } // FIX ME
+	| GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
+		{ throw SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; } // FIX ME
+	;
+
+generic_assoc_list:										// C11
+	| generic_association
+	| generic_assoc_list ',' generic_association
+	;
+
+generic_association:									// C11
+	type_no_function ':' assignment_expression
+	| DEFAULT ':' assignment_expression
 	;
 
@@ -767,4 +779,6 @@
 	| unary_expression assignment_operator assignment_expression
 		{ $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); }
+	| unary_expression '=' '{' initializer_list comma_opt '}' // FIX ME
+		{ $$ = nullptr; }
 	;
 
@@ -1050,4 +1064,6 @@
 	| RETURN comma_expression_opt ';'
 		{ $$ = new StatementNode( build_return( $2 ) ); }
+	| RETURN '{' initializer_list comma_opt '}'			// FIX ME
+		{ $$ = nullptr; }
 	| THROW assignment_expression_opt ';'				// handles rethrow
 		{ $$ = new StatementNode( build_throw( $2 ) ); }
@@ -1068,5 +1084,5 @@
 mutex_statement:
 	MUTEX '(' argument_expression_list ')' statement
-		{ throw SemanticError("Mutex statement is currently unimplemented."); $$ = nullptr; } // FIX ME
+		{ throw SemanticError( yylloc, "Mutex statement is currently unimplemented." ); $$ = nullptr; } // FIX ME
 	;
 
@@ -1289,5 +1305,5 @@
 static_assert:
 	STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11
-		{ throw SemanticError("Static assert is currently unimplemented."); $$ = nullptr; }	// FIX ME
+		{ throw SemanticError( yylloc, "Static assert is currently unimplemented." ); $$ = nullptr; }	// FIX ME
 
 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
@@ -2377,5 +2393,5 @@
 		{
 			linkageStack.push( linkage );				// handle nested extern "C"/"Cforall"
-			linkage = LinkageSpec::linkageUpdate( linkage, $2 );
+			linkage = LinkageSpec::linkageUpdate( yylloc, linkage, $2 );
 		}
 	  '{' external_definition_list_opt '}'
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -239,5 +239,5 @@
 				std::cerr << "No reasonable alternatives for expression " << expr << std::endl;
 			)
-			throw SemanticError( "No reasonable alternatives for expression ", expr );
+			throw SemanticError( expr, "No reasonable alternatives for expression " );
 		}
 		if ( prune ) {
@@ -257,5 +257,5 @@
 				stream << "Alternatives are:\n";
 				printAlts( winners, stream, 1 );
-				throw SemanticError( stream.str() );
+				throw SemanticError( expr->location, stream.str() );
 			}
 			alternatives = move(pruned);
@@ -494,5 +494,5 @@
 				return;
 			} else if ( level >= recursionLimit ) {
-				throw SemanticError( "Too many recursive assertions" );
+				throw SemanticError( newAlt.expr->location, "Too many recursive assertions" );
 			} else {
 				AssertionSet newerNeed;
@@ -1408,5 +1408,5 @@
 			findMinCost( finder.alternatives.begin(), finder.alternatives.end(), back_inserter( winners ) );
 			if ( winners.size() != 1 ) {
-				throw SemanticError( "Ambiguous expression in sizeof operand: ", sizeofExpr->get_expr() );
+				throw SemanticError( sizeofExpr->get_expr(), "Ambiguous expression in sizeof operand: " );
 			} // if
 			// return the lowest cost alternative for the argument
@@ -1429,5 +1429,5 @@
 			findMinCost( finder.alternatives.begin(), finder.alternatives.end(), back_inserter( winners ) );
 			if ( winners.size() != 1 ) {
-				throw SemanticError( "Ambiguous expression in alignof operand: ", alignofExpr->get_expr() );
+				throw SemanticError( alignofExpr->get_expr(), "Ambiguous expression in alignof operand: " );
 			} // if
 			// return the lowest cost alternative for the argument
Index: src/ResolvExpr/CurrentObject.cc
===================================================================
--- src/ResolvExpr/CurrentObject.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/ResolvExpr/CurrentObject.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -141,5 +141,5 @@
 			base = at->get_base();
 			memberIter = createMemberIterator( base );
-			if ( at->isVarLen ) throw SemanticError( "VLA initialization does not support @=", at );
+			if ( at->isVarLen ) throw SemanticError( at, "VLA initialization does not support @=" );
 			setSize( at->get_dimension() );
 		}
@@ -156,5 +156,5 @@
 					PRINT( std::cerr << "array type with size: " << size << std::endl; )
 				} catch ( SemanticError & ) {
-					throw SemanticError( "Constant expression of non-integral type in array dimension: ", expr );
+					throw SemanticError( expr, "Constant expression of non-integral type in array dimension: " );
 				}
 			}	else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
@@ -179,5 +179,5 @@
 					index = constExpr->intValue();
 				} catch( SemanticError & ) {
-					throw SemanticError( "Constant expression of non-integral type in array designator: ", expr );
+					throw SemanticError( expr, "Constant expression of non-integral type in array designator: " );
 				}
 			} else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
@@ -532,7 +532,7 @@
 		} // for
 		if ( desigAlts.size() > 1 ) {
-			throw SemanticError( toString("Too many alternatives (", desigAlts.size(), ") for designation: "), designation );
+			throw SemanticError( designation, toString("Too many alternatives (", desigAlts.size(), ") for designation: ") );
 		} else if ( desigAlts.size() == 0 ) {
-			throw SemanticError( "No reasonable alternatives for designation: ", designation );
+			throw SemanticError( designation, "No reasonable alternatives for designation: " );
 		}
 		DesignatorChain & d = desigAlts.back();
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/ResolvExpr/Resolver.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -174,5 +174,5 @@
 			findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) );
 			if ( winners.size() == 0 ) {
-				throw SemanticError( toString( "No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""), "expression: "), untyped );
+				throw SemanticError( untyped, toString( "No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""), "expression: ") );
 			} else if ( winners.size() != 1 ) {
 				std::ostringstream stream;
@@ -181,5 +181,5 @@
 				stream << "Alternatives are:\n";
 				printAlts( winners, stream, 1 );
-				throw SemanticError( stream.str() );
+				throw SemanticError( untyped->location, stream.str() );
 			}
 
@@ -187,5 +187,5 @@
 			Alternative & choice = winners.front();
 			if ( findDeletedExpr( choice.expr ) ) {
-				throw SemanticError( "Unique best alternative includes deleted identifier in ", choice.expr );
+				throw SemanticError( choice.expr, "Unique best alternative includes deleted identifier in " );
 			}
 			alt = std::move( choice );
@@ -484,5 +484,5 @@
 				ss << strict_dynamic_cast<NameExpr*>( clause.target.function )->name;
 				ss << "' in call to waitfor";
-				throw SemanticError( ss.str() );
+				throw SemanticError( stmt->location, ss.str() );
 			}
 
@@ -506,10 +506,10 @@
 					PointerType * pointer = dynamic_cast< PointerType* >( func.expr->get_result()->stripReferences() );
 					if( !pointer ) {
-						throw SemanticError( "candidate not viable: not a pointer type\n", func.expr->get_result() );
+						throw SemanticError( func.expr->get_result(), "candidate not viable: not a pointer type\n" );
 					}
 
 					FunctionType * function = dynamic_cast< FunctionType* >( pointer->get_base() );
 					if( !function ) {
-						throw SemanticError( "candidate not viable: not a function type\n", pointer->get_base() );
+						throw SemanticError( pointer->get_base(), "candidate not viable: not a function type\n" );
 					}
 
@@ -520,5 +520,5 @@
 
 						if( !advance_to_mutex( param, param_end ) ) {
-							throw SemanticError("candidate function not viable: no mutex parameters\n", function);
+							throw SemanticError(function, "candidate function not viable: no mutex parameters\n");
 						}
 					}
@@ -559,5 +559,5 @@
 									// We ran out of parameters but still have arguments
 									// this function doesn't match
-									throw SemanticError("candidate function not viable: too many mutex arguments\n", function);
+									throw SemanticError( function, "candidate function not viable: too many mutex arguments\n" );
 								}
 
@@ -571,5 +571,5 @@
 									(*param)->get_type()->print( ss );
 									ss << "'\n";
-									throw SemanticError(ss.str(), function);
+									throw SemanticError( function, ss.str() );
 								}
 
@@ -583,5 +583,5 @@
 								// We ran out of arguments but still have parameters left
 								// this function doesn't match
-								throw SemanticError("candidate function not viable: too few mutex arguments\n", function);
+								throw SemanticError( function, "candidate function not viable: too few mutex arguments\n" );
 							}
 
@@ -610,8 +610,8 @@
 
 			// Make sure we got the right number of arguments
-			if( func_candidates.empty() )    { SemanticError top( "No alternatives for function in call to waitfor"  ); top.append( errors ); throw top; }
-			if( args_candidates.empty() )    { SemanticError top( "No alternatives for arguments in call to waitfor" ); top.append( errors ); throw top; }
-			if( func_candidates.size() > 1 ) { SemanticError top( "Ambiguous function in call to waitfor"            ); top.append( errors ); throw top; }
-			if( args_candidates.size() > 1 ) { SemanticError top( "Ambiguous arguments in call to waitfor"           ); top.append( errors ); throw top; }
+			if( func_candidates.empty() )    { SemanticError top( stmt->location, "No alternatives for function in call to waitfor"  ); top.append( errors ); throw top; }
+			if( args_candidates.empty() )    { SemanticError top( stmt->location, "No alternatives for arguments in call to waitfor" ); top.append( errors ); throw top; }
+			if( func_candidates.size() > 1 ) { SemanticError top( stmt->location, "Ambiguous function in call to waitfor"            ); top.append( errors ); throw top; }
+			if( args_candidates.size() > 1 ) { SemanticError top( stmt->location, "Ambiguous arguments in call to waitfor"           ); top.append( errors ); throw top; }
 			// TODO: need to use findDeletedExpr to ensure no deleted identifiers are used.
 
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/SymTab/Indexer.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -443,10 +443,10 @@
 			// isomorphic to C type-compatibility, which it may not be.
 			if ( hasIncompatibleCDecl( name, mangleName, scope ) ) {
-				throw SemanticError( "conflicting overload of C function ", decl );
+				throw SemanticError( decl, "conflicting overload of C function " );
 			}
 		} else {
 			// Check that a Cforall declaration doesn't override any C declaration
 			if ( hasCompatibleCDecl( name, mangleName, scope ) ) {
-				throw SemanticError( "Cforall declaration hides C function ", decl );
+				throw SemanticError( decl, "Cforall declaration hides C function " );
 			}
 		}
@@ -463,10 +463,10 @@
 	void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
 		// default handling of conflicts is to raise an error
-		addId( decl, [decl](IdData &, const std::string & msg) { throw SemanticError( msg, decl ); return true; }, baseExpr );
+		addId( decl, [decl](IdData &, const std::string & msg) { throw SemanticError( decl, msg ); return true; }, baseExpr );
 	}
 
 	void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ) {
 		// default handling of conflicts is to raise an error
-		addId( decl, [decl](IdData &, const std::string & msg) { throw SemanticError( msg, decl ); return true; }, nullptr, deleteStmt );
+		addId( decl, [decl](IdData &, const std::string & msg) { throw SemanticError( decl, msg ); return true; }, nullptr, deleteStmt );
 	}
 
@@ -477,5 +477,5 @@
 			return true;
 		} else {
-			throw SemanticError( "redeclaration of ", added );
+			throw SemanticError( added, "redeclaration of " );
 		}
 	}
@@ -504,5 +504,5 @@
 			return false;
 		} else if ( ! added->get_members().empty() ) {
-			throw SemanticError( "redeclaration of ", added );
+			throw SemanticError( added, "redeclaration of " );
 		} // if
 		return true;
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/SymTab/Validate.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -361,5 +361,5 @@
 			// the only case in which "void" is valid is where it is the only one in the list
 			if ( containsVoid && ( nvals > 1 || isVarArgs ) ) {
-				throw SemanticError( "invalid type void in function type ", func );
+				throw SemanticError( func, "invalid type void in function type " );
 			}
 
@@ -402,5 +402,5 @@
 		for ( Expression * param : inst->parameters ) {
 			if ( ! dynamic_cast< TypeExpr * >( param ) ) {
-				throw SemanticError( "Expression parameters for generic types are currently unsupported: ", inst );
+				throw SemanticError( inst, "Expression parameters for generic types are currently unsupported: " );
 			}
 		}
@@ -502,8 +502,8 @@
 		TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
 		if ( ! traitDecl ) {
-			throw SemanticError( "use of undeclared trait " + traitInst->name );
+			throw SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name );
 		} // if
 		if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
-			throw SemanticError( "incorrect number of trait parameters: ", traitInst );
+			throw SemanticError( traitInst, "incorrect number of trait parameters: " );
 		} // if
 		traitInst->baseTrait = traitDecl;
@@ -513,5 +513,5 @@
 			TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) );
 			if ( ! expr ) {
-				throw SemanticError( "Expression parameters for trait instances are currently unsupported: ", std::get<1>(p) );
+				throw SemanticError( std::get<1>(p), "Expression parameters for trait instances are currently unsupported: " );
 			}
 			if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
@@ -619,5 +619,5 @@
 				bool isVoid = fixFunction( assertion );
 				if ( isVoid ) {
-					throw SemanticError( "invalid type void in assertion of function ", node );
+					throw SemanticError( node, "invalid type void in assertion of function " );
 				} // if
 			} // for
@@ -663,5 +663,5 @@
 		// were cast to void.
 		if ( ! returnStmt->get_expr() && returnVals.size() != 0 ) {
-			throw SemanticError( "Non-void function returns no values: " , returnStmt );
+			throw SemanticError( returnStmt, "Non-void function returns no values: " );
 		}
 	}
@@ -704,5 +704,5 @@
 				ReferenceToType *rtt = dynamic_cast<ReferenceToType*>(ret);
 				if ( ! rtt ) {
-					throw SemanticError("Cannot apply type parameters to base type of " + typeInst->name);
+					throw SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name );
 				}
 				rtt->get_parameters().clear();
@@ -742,5 +742,5 @@
 			Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
 			if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) {
-				throw SemanticError( "Cannot redefine typedef: " + tyDecl->name );
+				throw SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name );
 			}
 			// Cannot redefine VLA typedefs. Note: this is slightly incorrect, because our notion of VLAs
@@ -749,5 +749,5 @@
 			// to fix this corner case likely outweighs the utility of allowing it.
 			if ( isVariableLength( t1 ) || isVariableLength( t2 ) ) {
-				throw SemanticError( "Cannot redefine typedef: " + tyDecl->name );
+				throw SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name );
 			}
 		} else {
@@ -847,5 +847,5 @@
 				type = new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() );
 			} // if
-			TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), Type::StorageClasses(), type, aggDecl->get_linkage() ) );
+			TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type, aggDecl->get_linkage() ) );
 			typedefNames[ aggDecl->get_name() ] = std::make_pair( std::move( tyDecl ), scopeLevel );
 		} // if
@@ -898,12 +898,12 @@
 		if ( CodeGen::isCtorDtorAssign( funcDecl->get_name() ) ) { // TODO: also check /=, etc.
 			if ( params.size() == 0 ) {
-				throw SemanticError( "Constructors, destructors, and assignment functions require at least one parameter ", funcDecl );
+				throw SemanticError( funcDecl, "Constructors, destructors, and assignment functions require at least one parameter " );
 			}
 			ReferenceType * refType = dynamic_cast< ReferenceType * >( params.front()->get_type() );
 			if ( ! refType ) {
-				throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a reference ", funcDecl );
+				throw SemanticError( funcDecl, "First parameter of a constructor, destructor, or assignment function must be a reference " );
 			}
 			if ( CodeGen::isCtorDtor( funcDecl->get_name() ) && returnVals.size() != 0 ) {
-				throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
+				throw SemanticError( funcDecl, "Constructors and destructors cannot have explicit return values " );
 			}
 		}
@@ -940,6 +940,6 @@
 
 			sub.apply( inst );
-			if ( args.size() < params->size() ) throw SemanticError( "Too few type arguments in generic type ", inst );
-			if ( args.size() > params->size() ) throw SemanticError( "Too many type arguments in generic type ", inst );
+			if ( args.size() < params->size() ) throw SemanticError( inst, "Too few type arguments in generic type " );
+			if ( args.size() > params->size() ) throw SemanticError( inst, "Too many type arguments in generic type " );
 		}
 	}
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/SynTree/Declaration.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -245,5 +245,7 @@
 	typedef NamedTypeDecl Parent;
   public:
-	TypedefDecl( const std::string &name, Type::StorageClasses scs, Type *type, LinkageSpec::Spec spec = LinkageSpec::Cforall ) : Parent( name, scs, type ) { set_linkage( spec ); }
+	TypedefDecl( const std::string &name, CodeLocation location, Type::StorageClasses scs, Type *type, LinkageSpec::Spec spec = LinkageSpec::Cforall )
+		: Parent( name, scs, type ) { set_linkage( spec ); this->location = location; }
+
 	TypedefDecl( const TypedefDecl &other ) : Parent( other ) {}
 
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/SynTree/Expression.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -93,5 +93,5 @@
 		return 0;
 	}
-	throw SemanticError( "Constant expression of non-integral type ", this );
+	throw SemanticError( this, "Constant expression of non-integral type " );
 }
 
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/SynTree/Mutator.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -149,5 +149,4 @@
 			} // if
 		} catch( SemanticError &e ) {
-			e.set_location( (*i)->location );
 			errors.append( e );
 		} // try
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/SynTree/Statement.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -100,5 +100,5 @@
 	//actually this is a syntactic error signaled by the parser
 	if ( type == BranchStmt::Goto && target.empty() ) {
-		throw SemanticError("goto without target");
+		throw SemanticError( target.get_statement()->location, "goto without target");
 	}
 }
@@ -107,5 +107,5 @@
 	Statement(), computedTarget( computedTarget ), type( type ) {
 	if ( type != BranchStmt::Goto || computedTarget == nullptr ) {
-		throw SemanticError("Computed target not valid in branch statement");
+		throw SemanticError( computedTarget->location, "Computed target not valid in branch statement");
 	}
 }
@@ -203,5 +203,5 @@
 CaseStmt::CaseStmt( Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :
 	Statement(), condition( condition ), stmts( statements ), _isDefault( deflt ) {
-	if ( isDefault() && condition != 0 ) throw SemanticError("default case with condition: ", condition);
+	if ( isDefault() && condition != 0 ) throw SemanticError( condition, "default case with condition: " );
 }
 
Index: src/SynTree/TypeSubstitution.h
===================================================================
--- src/SynTree/TypeSubstitution.h	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/SynTree/TypeSubstitution.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -98,5 +98,5 @@
 				} // if
 			} else {
-				throw SemanticError( toString( "Attempt to provide non-type parameter: ", toString( *actualIt ).c_str(), " for type parameter " ), formal );
+				throw SemanticError( formal, toString( "Attempt to provide non-type parameter: ", toString( *actualIt ).c_str(), " for type parameter " ) );
 			} // if
 		} else {
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/SynTree/Visitor.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -143,5 +143,4 @@
 			}
 		} catch( SemanticError &e ) {
-			e.set_location( (*i)->location );
 			errors.append( e );
 		}
Index: src/libcfa/bits/cfatime.h
===================================================================
--- src/libcfa/bits/cfatime.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
+++ src/libcfa/bits/cfatime.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -0,0 +1,93 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// align.h --
+//
+// Author           : Thierry Delisle
+// Created On       : Mon Feb 12 18:06:59 2018
+// Last Modified By :
+// Last Modified On :
+// Update Count     : 0
+//
+// This  library is free  software; you  can redistribute  it and/or  modify it
+// under the terms of the GNU Lesser General Public License as published by the
+// Free Software  Foundation; either  version 2.1 of  the License, or  (at your
+// option) any later version.
+//
+// This library is distributed in the  hope that it will be useful, but WITHOUT
+// ANY  WARRANTY;  without even  the  implied  warranty  of MERCHANTABILITY  or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+// for more details.
+//
+// You should  have received a  copy of the  GNU Lesser General  Public License
+// along  with this library.
+//
+
+#pragma once
+
+extern "C" {
+#include <time.h>
+}
+
+#include "bits/defs.h"
+
+struct timespec;
+struct itimerval;
+
+//=============================================================================================
+// time type
+//=============================================================================================
+
+struct __cfa_time_t {
+	uint64_t val;
+};
+
+// ctors
+static inline void ?{}( __cfa_time_t & this ) { this.val = 0; }
+static inline void ?{}( __cfa_time_t & this, zero_t zero ) { this.val = 0; }
+
+static inline __cfa_time_t ?=?( __cfa_time_t & this, zero_t rhs ) {
+	this.val = 0;
+	return this;
+}
+
+// logical ops
+static inline bool ?==?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val == rhs.val; }
+static inline bool ?!=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val != rhs.val; }
+static inline bool ?>? ( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val >  rhs.val; }
+static inline bool ?<? ( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val <  rhs.val; }
+static inline bool ?>=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val >= rhs.val; }
+static inline bool ?<=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val <= rhs.val; }
+
+static inline bool ?==?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val == rhs; }
+static inline bool ?!=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val != rhs; }
+static inline bool ?>? ( __cfa_time_t lhs, zero_t rhs ) { return lhs.val >  rhs; }
+static inline bool ?<? ( __cfa_time_t lhs, zero_t rhs ) { return lhs.val <  rhs; }
+static inline bool ?>=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val >= rhs; }
+static inline bool ?<=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val <= rhs; }
+
+// addition/substract
+static inline __cfa_time_t ?+?( __cfa_time_t lhs, __cfa_time_t rhs ) {
+	__cfa_time_t ret;
+	ret.val = lhs.val + rhs.val;
+	return ret;
+}
+
+static inline __cfa_time_t ?-?( __cfa_time_t lhs, __cfa_time_t rhs ) {
+	__cfa_time_t ret;
+	ret.val = lhs.val - rhs.val;
+	return ret;
+}
+
+static inline __cfa_time_t ?`cfa_s ( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000_000_000ul; return ret; }
+static inline __cfa_time_t ?`cfa_ms( uint64_t val ) { __cfa_time_t ret; ret.val = val *     1_000_000ul; return ret; }
+static inline __cfa_time_t ?`cfa_us( uint64_t val ) { __cfa_time_t ret; ret.val = val *         1_000ul; return ret; }
+static inline __cfa_time_t ?`cfa_ns( uint64_t val ) { __cfa_time_t ret; ret.val = val *             1ul; return ret; }
+
+static inline __cfa_time_t from_s  ( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000_000_000ul; return ret; }
+static inline __cfa_time_t from_ms ( uint64_t val ) { __cfa_time_t ret; ret.val = val *     1_000_000ul; return ret; }
+static inline __cfa_time_t from_us ( uint64_t val ) { __cfa_time_t ret; ret.val = val *         1_000ul; return ret; }
+static inline __cfa_time_t from_ns ( uint64_t val ) { __cfa_time_t ret; ret.val = val *             1ul; return ret; }
Index: src/libcfa/concurrency/alarm.c
===================================================================
--- src/libcfa/concurrency/alarm.c	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/libcfa/concurrency/alarm.c	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -18,5 +18,4 @@
 #include <stdio.h>
 #include <string.h>
-#include <time.h>
 #include <unistd.h>
 #include <sys/time.h>
@@ -27,41 +26,17 @@
 #include "preemption.h"
 
-//=============================================================================================
-// time type
-//=============================================================================================
 
-#define one_second         1_000_000_000ul
-#define one_milisecond         1_000_000ul
-#define one_microsecond            1_000ul
-#define one_nanosecond                 1ul
-
-__cfa_time_t zero_time = { 0 };
-
-void ?{}( __cfa_time_t & this ) { this.val = 0; }
-void ?{}( __cfa_time_t & this, zero_t zero ) { this.val = 0; }
-
-void ?{}( itimerval & this, __cfa_time_t * alarm ) with( this ) {
-	it_value.tv_sec = alarm->val / one_second;			// seconds
-	it_value.tv_usec = max( (alarm->val % one_second) / one_microsecond, 1000 ); // microseconds
+static inline void ?{}( itimerval & this, __cfa_time_t * alarm ) with( this ) {
+	it_value.tv_sec = alarm->val / (1`cfa_s).val;			// seconds
+	it_value.tv_usec = max( (alarm->val % (1`cfa_s).val) / (1`cfa_us).val, 1000 ); // microseconds
 	it_interval.tv_sec = 0;
 	it_interval.tv_usec = 0;
 }
 
-
-void ?{}( __cfa_time_t & this, timespec * curr ) {
+static inline void ?{}( __cfa_time_t & this, timespec * curr ) {
 	uint64_t secs  = curr->tv_sec;
 	uint64_t nsecs = curr->tv_nsec;
-	this.val = (secs * one_second) + nsecs;
+	this.val = from_s(secs).val + nsecs;
 }
-
-__cfa_time_t ?=?( __cfa_time_t & this, zero_t rhs ) {
-	this.val = 0;
-	return this;
-}
-
-__cfa_time_t from_s ( uint64_t val ) { __cfa_time_t ret; ret.val = val * 1_000_000_000ul; return ret; }
-__cfa_time_t from_ms( uint64_t val ) { __cfa_time_t ret; ret.val = val *     1_000_000ul; return ret; }
-__cfa_time_t from_us( uint64_t val ) { __cfa_time_t ret; ret.val = val *         1_000ul; return ret; }
-__cfa_time_t from_ns( uint64_t val ) { __cfa_time_t ret; ret.val = val *             1ul; return ret; }
 
 //=============================================================================================
@@ -84,5 +59,5 @@
 //=============================================================================================
 
-void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) with( this ) {
+void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s ) with( this ) {
 	this.thrd = thrd;
 	this.alarm = alarm;
@@ -93,5 +68,5 @@
 }
 
-void ?{}( alarm_node_t & this, processor   * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) with( this ) {
+void ?{}( alarm_node_t & this, processor   * proc, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s ) with( this ) {
 	this.proc = proc;
 	this.alarm = alarm;
Index: src/libcfa/concurrency/alarm.h
===================================================================
--- src/libcfa/concurrency/alarm.h	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/libcfa/concurrency/alarm.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -21,60 +21,8 @@
 #include <assert.h>
 
+#include "bits/cfatime.h"
+
 struct thread_desc;
 struct processor;
-
-struct timespec;
-struct itimerval;
-
-//=============================================================================================
-// time type
-//=============================================================================================
-
-struct __cfa_time_t {
-	uint64_t val;
-};
-
-// ctors
-void ?{}( __cfa_time_t & this );
-void ?{}( __cfa_time_t & this, zero_t zero );
-void ?{}( __cfa_time_t & this, timespec * curr );
-void ?{}( itimerval & this, __cfa_time_t * alarm );
-
-__cfa_time_t ?=?( __cfa_time_t & this, zero_t rhs );
-
-// logical ops
-static inline bool ?==?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val == rhs.val; }
-static inline bool ?!=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val != rhs.val; }
-static inline bool ?>? ( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val >  rhs.val; }
-static inline bool ?<? ( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val <  rhs.val; }
-static inline bool ?>=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val >= rhs.val; }
-static inline bool ?<=?( __cfa_time_t lhs, __cfa_time_t rhs ) { return lhs.val <= rhs.val; }
-
-static inline bool ?==?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val == rhs; }
-static inline bool ?!=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val != rhs; }
-static inline bool ?>? ( __cfa_time_t lhs, zero_t rhs ) { return lhs.val >  rhs; }
-static inline bool ?<? ( __cfa_time_t lhs, zero_t rhs ) { return lhs.val <  rhs; }
-static inline bool ?>=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val >= rhs; }
-static inline bool ?<=?( __cfa_time_t lhs, zero_t rhs ) { return lhs.val <= rhs; }
-
-// addition/substract
-static inline __cfa_time_t ?+?( __cfa_time_t lhs, __cfa_time_t rhs ) {
-	__cfa_time_t ret;
-	ret.val = lhs.val + rhs.val;
-	return ret;
-}
-
-static inline __cfa_time_t ?-?( __cfa_time_t lhs, __cfa_time_t rhs ) {
-	__cfa_time_t ret;
-	ret.val = lhs.val - rhs.val;
-	return ret;
-}
-
-__cfa_time_t from_s ( uint64_t );
-__cfa_time_t from_ms( uint64_t );
-__cfa_time_t from_us( uint64_t );
-__cfa_time_t from_ns( uint64_t );
-
-extern __cfa_time_t zero_time;
 
 //=============================================================================================
@@ -105,6 +53,6 @@
 typedef alarm_node_t ** __alarm_it_t;
 
-void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time );
-void ?{}( alarm_node_t & this, processor   * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time );
+void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s );
+void ?{}( alarm_node_t & this, processor   * proc, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s );
 void ^?{}( alarm_node_t & this );
 
Index: src/libcfa/concurrency/coroutine.c
===================================================================
--- src/libcfa/concurrency/coroutine.c	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/libcfa/concurrency/coroutine.c	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -99,4 +99,5 @@
 // Wrapper for co
 void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
+	verify( preemption.enabled || this_processor->do_terminate );
 	disable_interrupts();
 
@@ -116,4 +117,5 @@
 
 	enable_interrupts( __cfaabi_dbg_ctx );
+	verify( preemption.enabled || this_processor->do_terminate );
 } //ctxSwitchDirect
 
Index: src/libcfa/concurrency/invoke.c
===================================================================
--- src/libcfa/concurrency/invoke.c	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/libcfa/concurrency/invoke.c	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -28,4 +28,5 @@
 extern void __suspend_internal(void);
 extern void __leave_coroutine(void);
+extern void __finish_creation(void);
 extern void __leave_thread_monitor( struct thread_desc * this );
 extern void disable_interrupts();
@@ -44,4 +45,6 @@
 
 	cor->state = Active;
+
+	enable_interrupts( __cfaabi_dbg_ctx );
 
 	main( this );
@@ -62,5 +65,5 @@
 	// First suspend, once the thread arrives here,
 	// the function pointer to main can be invalidated without risk
-	__suspend_internal();
+	__finish_creation();
 
 	// Fetch the thread handle from the user defined thread structure
Index: src/libcfa/concurrency/kernel.c
===================================================================
--- src/libcfa/concurrency/kernel.c	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/libcfa/concurrency/kernel.c	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -56,7 +56,9 @@
 thread_local processor *      volatile this_processor;
 
-volatile thread_local bool preemption_in_progress = 0;
-volatile thread_local bool preemption_enabled = false;
-volatile thread_local unsigned short disable_preempt_count = 1;
+// volatile thread_local bool preemption_in_progress = 0;
+// volatile thread_local bool preemption_enabled = false;
+// volatile thread_local unsigned short disable_preempt_count = 1;
+
+volatile thread_local __cfa_kernel_preemption_data_t preemption = { false, false, 1 };
 
 //-----------------------------------------------------------------------------
@@ -207,9 +209,9 @@
 			if(readyThread)
 			{
-				verify( !preemption_enabled );
+				verify( !preemption.enabled );
 
 				runThread(this, readyThread);
 
-				verify( !preemption_enabled );
+				verify( !preemption.enabled );
 
 				//Some actions need to be taken from the kernel
@@ -260,5 +262,5 @@
 void finishRunning(processor * this) with( this->finish ) {
 	if( action_code == Release ) {
-		verify( !preemption_enabled );
+		verify( !preemption.enabled );
 		unlock( *lock );
 	}
@@ -267,10 +269,10 @@
 	}
 	else if( action_code == Release_Schedule ) {
-		verify( !preemption_enabled );
+		verify( !preemption.enabled );
 		unlock( *lock );
 		ScheduleThread( thrd );
 	}
 	else if( action_code == Release_Multi ) {
-		verify( !preemption_enabled );
+		verify( !preemption.enabled );
 		for(int i = 0; i < lock_count; i++) {
 			unlock( *locks[i] );
@@ -304,6 +306,6 @@
 	this_coroutine = NULL;
 	this_thread = NULL;
-	preemption_enabled = false;
-	disable_preempt_count = 1;
+	preemption.enabled = false;
+	preemption.disable_count = 1;
 	// SKULLDUGGERY: We want to create a context for the processor coroutine
 	// which is needed for the 2-step context switch. However, there is no reason
@@ -345,4 +347,42 @@
 }
 
+void kernel_first_resume(processor * this) {
+	coroutine_desc * src = this_coroutine;
+	coroutine_desc * dst = get_coroutine(*this->runner);
+
+	verify( !preemption.enabled );
+
+	create_stack(&dst->stack, dst->stack.size);
+	CtxStart(this->runner, CtxInvokeCoroutine);
+
+	verify( !preemption.enabled );
+
+	dst->last = src;
+	dst->starter = dst->starter ? dst->starter : src;
+
+	// set state of current coroutine to inactive
+	src->state = src->state == Halted ? Halted : Inactive;
+
+	// set new coroutine that task is executing
+	this_coroutine = dst;
+
+	// SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
+	// Therefore, when first creating a coroutine, interrupts are enable before calling the main.
+	// This is consistent with thread creation. However, when creating the main processor coroutine,
+	// we wan't interrupts to be disabled. Therefore, we double-disable interrupts here so they will
+	// stay disabled.
+	disable_interrupts();
+
+	// context switch to specified coroutine
+	assert( src->stack.context );
+	CtxSwitch( src->stack.context, dst->stack.context );
+	// when CtxSwitch returns we are back in the src coroutine
+
+	// set state of new coroutine to active
+	src->state = Active;
+
+	verify( !preemption.enabled );
+}
+
 //-----------------------------------------------------------------------------
 // Scheduler routines
@@ -352,5 +392,5 @@
 	verify( thrd->self_cor.state != Halted );
 
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 
 	verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
@@ -362,13 +402,13 @@
 	}
 
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 }
 
 thread_desc * nextThread(cluster * this) with( *this ) {
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 	lock( ready_queue_lock __cfaabi_dbg_ctx2 );
 	thread_desc * head = pop_head( ready_queue );
 	unlock( ready_queue_lock );
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 	return head;
 }
@@ -376,7 +416,7 @@
 void BlockInternal() {
 	disable_interrupts();
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 	returnToKernel();
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 	enable_interrupts( __cfaabi_dbg_ctx );
 }
@@ -387,7 +427,7 @@
 	this_processor->finish.lock        = lock;
 
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 	returnToKernel();
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 
 	enable_interrupts( __cfaabi_dbg_ctx );
@@ -399,7 +439,7 @@
 	this_processor->finish.thrd        = thrd;
 
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 	returnToKernel();
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 
 	enable_interrupts( __cfaabi_dbg_ctx );
@@ -413,7 +453,7 @@
 	this_processor->finish.thrd        = thrd;
 
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 	returnToKernel();
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 
 	enable_interrupts( __cfaabi_dbg_ctx );
@@ -426,7 +466,7 @@
 	this_processor->finish.lock_count  = count;
 
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 	returnToKernel();
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 
 	enable_interrupts( __cfaabi_dbg_ctx );
@@ -441,7 +481,7 @@
 	this_processor->finish.thrd_count  = thrd_count;
 
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 	returnToKernel();
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 
 	enable_interrupts( __cfaabi_dbg_ctx );
@@ -449,5 +489,5 @@
 
 void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
-	verify( !preemption_enabled );
+	verify( !preemption.enabled );
 	this_processor->finish.action_code = thrd ? Release_Schedule : Release;
 	this_processor->finish.lock        = lock;
@@ -463,4 +503,5 @@
 // Kernel boot procedures
 void kernel_startup(void) {
+	verify( !preemption.enabled );
 	__cfaabi_dbg_print_safe("Kernel : Starting\n");
 
@@ -500,5 +541,5 @@
 	// context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
 	// mainThread is on the ready queue when this call is made.
-	resume( *mainProcessor->runner );
+	kernel_first_resume( this_processor );
 
 
@@ -507,5 +548,7 @@
 	__cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
 
+	verify( !preemption.enabled );
 	enable_interrupts( __cfaabi_dbg_ctx );
+	verify( preemption.enabled );
 }
 
@@ -513,5 +556,7 @@
 	__cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
 
+	verify( preemption.enabled );
 	disable_interrupts();
+	verify( !preemption.enabled );
 
 	// SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
Index: src/libcfa/concurrency/kernel_private.h
===================================================================
--- src/libcfa/concurrency/kernel_private.h	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/libcfa/concurrency/kernel_private.h	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -74,7 +74,15 @@
 extern thread_local processor *      volatile this_processor;
 
-extern volatile thread_local bool preemption_in_progress;
-extern volatile thread_local bool preemption_enabled;
-extern volatile thread_local unsigned short disable_preempt_count;
+// extern volatile thread_local bool preemption_in_progress;
+// extern volatile thread_local bool preemption_enabled;
+// extern volatile thread_local unsigned short disable_preempt_count;
+
+struct __cfa_kernel_preemption_data_t {
+	bool enabled;
+	bool in_progress;
+	unsigned short disable_count;
+};
+
+extern volatile thread_local __cfa_kernel_preemption_data_t preemption;
 
 //-----------------------------------------------------------------------------
Index: src/libcfa/concurrency/monitor.c
===================================================================
--- src/libcfa/concurrency/monitor.c	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/libcfa/concurrency/monitor.c	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -10,6 +10,6 @@
 // Created On       : Thd Feb 23 12:27:26 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Feb  8 16:12:20 2018
-// Update Count     : 4
+// Last Modified On : Fri Feb 16 14:49:53 2018
+// Update Count     : 5
 //
 
@@ -427,5 +427,5 @@
 		thread_desc * this_thrd = this_thread;
 		if ( this.monitor_count != this_thrd->monitors.size ) {
-			abort( "Signal on condition %p made with different number of monitor(s), expected %li got %li", &this, this.monitor_count, this_thrd->monitors.size );
+			abort( "Signal on condition %p made with different number of monitor(s), expected %zi got %zi", &this, this.monitor_count, this_thrd->monitors.size );
 		}
 
Index: src/libcfa/concurrency/preemption.c
===================================================================
--- src/libcfa/concurrency/preemption.c	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/libcfa/concurrency/preemption.c	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -149,7 +149,7 @@
 	// Disable interrupts by incrementing the counter
 	void disable_interrupts() {
-		preemption_enabled = false;
-		__attribute__((unused)) unsigned short new_val = disable_preempt_count + 1;
-		disable_preempt_count = new_val;
+		preemption.enabled = false;
+		__attribute__((unused)) unsigned short new_val = preemption.disable_count + 1;
+		preemption.disable_count = new_val;
 		verify( new_val < 65_000u );              // If this triggers someone is disabling interrupts without enabling them
 	}
@@ -161,11 +161,11 @@
 		thread_desc * thrd = this_thread;         // Cache the thread now since interrupts can start happening after the atomic add
 
-		unsigned short prev = disable_preempt_count;
-		disable_preempt_count -= 1;
+		unsigned short prev = preemption.disable_count;
+		preemption.disable_count -= 1;
 		verify( prev != 0u );                     // If this triggers someone is enabled already enabled interruptsverify( prev != 0u );
 
 		// Check if we need to prempt the thread because an interrupt was missed
 		if( prev == 1 ) {
-			preemption_enabled = true;
+			preemption.enabled = true;
 			if( proc->pending_preemption ) {
 				proc->pending_preemption = false;
@@ -181,9 +181,9 @@
 	// Don't execute any pending CtxSwitch even if counter reaches 0
 	void enable_interrupts_noPoll() {
-		unsigned short prev = disable_preempt_count;
-		disable_preempt_count -= 1;
+		unsigned short prev = preemption.disable_count;
+		preemption.disable_count -= 1;
 		verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
 		if( prev == 1 ) {
-			preemption_enabled = true;
+			preemption.enabled = true;
 		}
 	}
@@ -235,5 +235,5 @@
 // If false : preemption is unsafe and marked as pending
 static inline bool preemption_ready() {
-	bool ready = preemption_enabled && !preemption_in_progress; // Check if preemption is safe
+	bool ready = preemption.enabled && !preemption.in_progress; // Check if preemption is safe
 	this_processor->pending_preemption = !ready;                        // Adjust the pending flag accordingly
 	return ready;
@@ -250,6 +250,6 @@
 
 	// Start with preemption disabled until ready
-	preemption_enabled = false;
-	disable_preempt_count = 1;
+	preemption.enabled = false;
+	preemption.disable_count = 1;
 
 	// Initialize the event kernel
@@ -290,5 +290,5 @@
 // Used by thread to control when they want to receive preemption signals
 void ?{}( preemption_scope & this, processor * proc ) {
-	(this.alarm){ proc, zero_time, zero_time };
+	(this.alarm){ proc, 0`cfa_s, 0`cfa_s };
 	this.proc = proc;
 	this.proc->preemption_alarm = &this.alarm;
@@ -300,5 +300,5 @@
 	disable_interrupts();
 
-	update_preemption( this.proc, zero_time );
+	update_preemption( this.proc, 0`cfa_s );
 }
 
@@ -330,7 +330,7 @@
 	__cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
 
-	preemption_in_progress = true;                      // Sync flag : prevent recursive calls to the signal handler
+	preemption.in_progress = true;                      // Sync flag : prevent recursive calls to the signal handler
 	signal_unblock( SIGUSR1 );                          // We are about to CtxSwitch out of the signal handler, let other handlers in
-	preemption_in_progress = false;                     // Clear the in progress flag
+	preemption.in_progress = false;                     // Clear the in progress flag
 
 	// Preemption can occur here
Index: src/libcfa/concurrency/thread.c
===================================================================
--- src/libcfa/concurrency/thread.c	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/libcfa/concurrency/thread.c	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -90,6 +90,15 @@
 }
 
+extern "C" {
+	void __finish_creation(void) {
+		coroutine_desc* thrd_c = this_coroutine;
+		ThreadCtxSwitch( thrd_c, thrd_c->last );
+	}
+}
+
 void yield( void ) {
+	verify( preemption.enabled );
 	BlockInternal( this_thread );
+	verify( preemption.enabled );
 }
 
Index: src/main.cc
===================================================================
--- src/main.cc	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/main.cc	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -282,4 +282,6 @@
 		} // if
 
+		CodeTools::fillLocations( translationUnit );
+
 		OPTPRINT( "resolve" )
 		ResolvExpr::resolve( translationUnit );
@@ -361,5 +363,5 @@
 			cerr << endl << "---End of AST, begin error message:---\n" << endl;
 		} // if
-		e.print( cerr );
+		e.print();
 		if ( output != &cout ) {
 			delete output;
Index: src/tests/.expect/alloc.txt
===================================================================
--- src/tests/.expect/alloc.txt	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/tests/.expect/alloc.txt	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -2,5 +2,5 @@
 CFA malloc 0xdeadbeef
 CFA alloc 0xdeadbeef
-CFA alloc, fill 01010101
+CFA alloc, fill ffffffff
 
 C   array calloc, fill 0
@@ -10,6 +10,6 @@
 CFA array alloc, no fill
 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 
-CFA array alloc, fill 0x1
-0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 
+CFA array alloc, fill 0xff
+0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 
 
 C   realloc
@@ -25,9 +25,9 @@
 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 
 CFA resize array alloc, fill
-0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 
+0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 
 CFA resize array alloc, fill
-0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 
+0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 
 CFA resize array alloc, fill
-0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 
+0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 
 
 C   memalign 42 42.5
@@ -37,18 +37,18 @@
 CFA aligned_alloc 42 42.5
 CFA align_alloc 42 42.5
-CFA align_alloc fill 0x1010101 0x1.1010101010101p-1007
+CFA align_alloc fill 0xffffffff -nan
 
 CFA array align_alloc
 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 42 42.5, 
 CFA array align_alloc, fill
-0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 
+0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 
 
-CFA memset 0x1010101 0x1.1010101010101p-1007
-CFA memcpy 0x1010101 0x1.1010101010101p-1007
+CFA memset 0xffffffff -nan
+CFA memcpy 0xffffffff -nan
 
 CFA array memset
-0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 
+0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 
 CFA memcpy
-0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 0x1010101 0x1.1010101010101p-1007, 
+0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 0xffffffff -nan, 
 
 CFA new initialize
Index: src/tests/alloc.c
===================================================================
--- src/tests/alloc.c	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/tests/alloc.c	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -10,6 +10,6 @@
 // Created On       : Wed Feb  3 07:56:22 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Jan 22 21:26:40 2018
-// Update Count     : 326
+// Last Modified On : Fri Feb 16 15:42:31 2018
+// Update Count     : 330
 //
 
@@ -27,6 +27,6 @@
 int main( void ) {
 	size_t dim = 10;
+	char fill = '\xff';
 	int * p;
-	char fill = '\1';
 
 	// allocation, non-array types
@@ -79,5 +79,5 @@
 
 	p = alloc( 2 * dim, fill );                         // CFA array alloc, fill
-	printf( "CFA array alloc, fill %#x\n", fill );
+	printf( "CFA array alloc, fill %#hhx\n", fill );
 	for ( int i = 0; i < 2 * dim; i += 1 ) { printf( "%#x ", p[i] ); }
 	printf( "\n" );
Index: src/tests/raii/.expect/dtor-early-exit-ERR2.txt
===================================================================
--- src/tests/raii/.expect/dtor-early-exit-ERR2.txt	(revision c71b2568066cb39013d366dd0195e430de881e0e)
+++ src/tests/raii/.expect/dtor-early-exit-ERR2.txt	(revision 7c782aff4b836a71e18dd75c37d3b3e43582a5bc)
@@ -1,3 +1,3 @@
-raii/dtor-early-exit.c:220:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)
+raii/dtor-early-exit.c:217:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)
   with target: L2
   with original target: L2
