Index: doc/theses/thierry_delisle/.gitignore
===================================================================
--- doc/theses/thierry_delisle/.gitignore	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ doc/theses/thierry_delisle/.gitignore	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -25,4 +25,5 @@
 *.pdf
 *.png
+*.ps
 figures/*.tex
 
Index: doc/theses/thierry_delisle/Makefile
===================================================================
--- doc/theses/thierry_delisle/Makefile	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ doc/theses/thierry_delisle/Makefile	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -88,11 +88,11 @@
 	mkdir -p ${Build}
 
-%.tex : %.fig
+%.tex : %.fig ${Build}
 	fig2dev -L eepic $< > ${Build}/$@
 
-%.ps : %.fig
+%.ps : %.fig ${Build}
 	fig2dev -L ps $< > ${Build}/$@
 
-%.pstex : %.fig
+%.pstex : %.fig ${Build}
 	fig2dev -L pstex $< > ${Build}/$@
 	fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
@@ -101,5 +101,5 @@
 # Tools to generate png files
 # to create a png we create a pdf and convert it to png
-%.png : build/%.pstex figures/%.tex
+%.png : build/%.pstex figures/%.tex ${Build}
 	echo ${basename $@}
 	${LaTeX} figures/${basename $@}.tex
@@ -109,5 +109,5 @@
 
 # creating a pdf of a figure requires generating some latex that just includes the figure
-figures/%.tex: build/%.pstex
+figures/%.tex: build/%.pstex ${Build}
 	echo -n 	"\documentclass[preview]{standalone}\n" 	\
 			"\usepackage[T1]{fontenc}\n" 			\
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/Common/PassVisitor.impl.h	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -828,6 +828,11 @@
 	VISIT_START( node );
 
-	visitExpression( node->condition );
-	node->body = visitStatement( node->body );
+	{
+		// while statements introduce a level of scope (for the initialization)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->initialization, *this );
+		visitExpression ( node->condition );
+		node->body = visitStatement( node->body );
+	}
 
 	VISIT_END( node );
@@ -838,6 +843,12 @@
 	MUTATE_START( node );
 
-	node->condition = mutateExpression( node->condition );
-	node->body      = mutateStatement ( node->body      );
+	{
+		// while statements introduce a level of scope (for the initialization)
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeMutate_impl( node->initialization, *this );
+		node->condition = mutateExpression( node->condition );
+		node->body      = mutateStatement ( node->body      );
+	}
+
 
 	MUTATE_END( Statement, node );
Index: src/ControlStruct/ForExprMutator.cc
===================================================================
--- src/ControlStruct/ForExprMutator.cc	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/ControlStruct/ForExprMutator.cc	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -45,4 +45,7 @@
 		return hoist( forStmt, forStmt->initialization );
 	}
+	Statement *ForExprMutator::postmutate( WhileStmt *whileStmt ) {
+		return hoist( whileStmt, whileStmt->initialization );
+	}
 } // namespace ControlStruct
 
Index: src/ControlStruct/ForExprMutator.h
===================================================================
--- src/ControlStruct/ForExprMutator.h	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/ControlStruct/ForExprMutator.h	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -18,4 +18,5 @@
 class IfStmt;
 class ForStmt;
+class WhileStmt;
 class Statement;
 
@@ -25,4 +26,5 @@
 		Statement *postmutate( IfStmt * );
 		Statement *postmutate( ForStmt * );
+		Statement *postmutate( WhileStmt * );
 	};
 } // namespace ControlStruct
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/Parser/ParseNode.h	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -403,4 +403,5 @@
 };
 
+Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init );
 Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/Parser/StatementNode.cc	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -80,19 +80,5 @@
 }
 
-Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) {
-	Statement * thenb, * elseb = 0;
-	std::list< Statement * > branches;
-	buildMoveList< Statement, StatementNode >( then_stmt, branches );
-	assert( branches.size() == 1 );
-	thenb = branches.front();
-
-	if ( else_stmt ) {
-		std::list< Statement * > branches;
-		buildMoveList< Statement, StatementNode >( else_stmt, branches );
-		assert( branches.size() == 1 );
-		elseb = branches.front();
-	} // if
-
-	std::list< Statement * > init;
+Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init ) {
 	if ( ctl->init != 0 ) {
 		buildMoveList( ctl->init, init );
@@ -102,5 +88,5 @@
 	if ( ctl->condition ) {
 		// compare the provided condition against 0
-		cond =  notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) );
+		cond = notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) );
 	} else {
 		for ( Statement * stmt : init ) {
@@ -113,4 +99,23 @@
 	}
 	delete ctl;
+	return cond;
+}
+
+Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) {
+	Statement * thenb, * elseb = 0;
+	std::list< Statement * > branches;
+	buildMoveList< Statement, StatementNode >( then_stmt, branches );
+	assert( branches.size() == 1 );
+	thenb = branches.front();
+
+	if ( else_stmt ) {
+		std::list< Statement * > branches;
+		buildMoveList< Statement, StatementNode >( else_stmt, branches );
+		assert( branches.size() == 1 );
+		elseb = branches.front();
+	} // if
+
+	std::list< Statement * > init;
+	Expression * cond = build_if_control( ctl, init );
 	return new IfStmt( cond, thenb, elseb, init );
 }
@@ -144,5 +149,7 @@
 	buildMoveList< Statement, StatementNode >( stmt, branches );
 	assert( branches.size() == 1 );
-	return new WhileStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), kind );
+
+	std::list< Statement * > init;
+	return new WhileStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), init, kind );
 }
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/ResolvExpr/Resolver.cc	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -207,5 +207,5 @@
 			Alternative & choice = winners.front();
 			if ( findDeletedExpr( choice.expr ) ) {
-				SemanticError( choice.expr, "Unique best alternative includes deleted identifier in " );
+				SemanticError( untyped->location, choice.expr, "Unique best alternative includes deleted identifier in " );
 			}
 			alt = std::move( choice );
@@ -242,4 +242,5 @@
 
 		static CastExpr untyped( nullptr ); // cast to void
+		untyped.location = expr->location;
 
 		// set up and resolve expression cast to void
@@ -274,5 +275,8 @@
 	void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer ) {
 		assert( untyped && type );
+		// transfer location to generated cast for error purposes
+		CodeLocation location = untyped->location;
 		untyped = new CastExpr( untyped, type );
+		untyped->location = location;
 		findSingleExpression( untyped, indexer );
 		removeExtraneousCast( untyped, indexer );
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/SymTab/Indexer.cc	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -106,19 +106,14 @@
 		if ( ! CodeGen::isCtorDtorAssign( id ) ) return;
 
-		// helpful data structure
+		// helpful data structure to organize properties for a type
 		struct ValueType {
-			struct DeclBall {
+			struct DeclBall { // properties for this particular decl
 				IdData decl;
-				bool isUserDefinedFunc; // properties for this particular decl
-				bool isDefaultCtor;
-				bool isDtor;
+				bool isUserDefinedFunc;
 				bool isCopyFunc;
 			};
 			// properties for this type
-			bool existsUserDefinedFunc = false;    // any user-defined function found
-			bool existsUserDefinedCtor = false;    // any user-defined constructor found
-			bool existsUserDefinedDtor = false;    // any user-defined destructor found
 			bool existsUserDefinedCopyFunc = false;    // user-defined copy ctor found
-			bool existsUserDefinedDefaultCtor = false; // user-defined default ctor found
+			BaseSyntaxNode * deleteStmt = nullptr;     // non-null if a user-defined function is found
 			std::list< DeclBall > decls;
 
@@ -127,14 +122,13 @@
 			ValueType & operator+=( IdData data ) {
 				DeclarationWithType * function = data.id;
-				bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() );
-				bool isDefaultCtor = InitTweak::isDefaultConstructor( function );
-				bool isDtor = InitTweak::isDestructor( function );
-				bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() );
-				decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );
-				existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc;
-				existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) );
-				existsUserDefinedDtor = existsUserDefinedDtor || (isUserDefinedFunc && isDtor);
+				bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );
+				bool isCopyFunc = InitTweak::isCopyFunction( function, function->name );
+				decls.push_back( DeclBall{ data, isUserDefinedFunc, isCopyFunc } );
 				existsUserDefinedCopyFunc = existsUserDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc);
-				existsUserDefinedDefaultCtor = existsUserDefinedDefaultCtor || (isUserDefinedFunc && isDefaultCtor);
+				if ( isUserDefinedFunc && ! data.deleteStmt ) {
+					// any user-defined function can act as an implicit delete statement for generated constructors.
+					// a delete stmt should not act as an implicit delete statement.
+					deleteStmt = data.id;
+				}
 				return *this;
 			}
@@ -160,21 +154,23 @@
 
 		// if a type contains user defined ctor/dtor/assign, then special rules trigger, which determine
-		// the set of ctor/dtor/assign that are seen by the requester. In particular, if the user defines
-		// a default ctor, then the generated default ctor should never be seen, likewise for copy ctor
-		// and dtor. If the user defines any ctor/dtor, then no generated field ctors should be seen.
-		// If the user defines any ctor then the generated default ctor should not be seen (intrinsic default
-		// ctor must be overridden exactly).
+		// the set of ctor/dtor/assign that can be used  by the requester. In particular, if the user defines
+		// a default ctor, then the generated default ctor is unavailable, likewise for copy ctor
+		// and dtor. If the user defines any ctor/dtor, then no generated field ctors are available.
+		// If the user defines any ctor then the generated default ctor is unavailable (intrinsic default
+		// ctor must be overridden exactly). If the user defines anything that looks like a copy constructor,
+		// then the generated copy constructor is unavailable, and likewise for the assignment operator.
 		for ( std::pair< const std::string, ValueType > & pair : funcMap ) {
 			ValueType & val = pair.second;
 			for ( ValueType::DeclBall ball : val.decls ) {
-				bool noUserDefinedFunc = ! val.existsUserDefinedFunc;
-				bool isUserDefinedFunc = ball.isUserDefinedFunc;
-				bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->linkage == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
-				bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator
-				bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor;
-				if ( noUserDefinedFunc || isUserDefinedFunc || isAcceptableDefaultCtor || isAcceptableCopyFunc || isAcceptableDtor ) {
-					// decl conforms to the rules described above, so it should be seen by the requester
-					out.push_back( ball.decl );
+				bool isNotUserDefinedFunc = ! ball.isUserDefinedFunc && ball.decl.id->linkage != LinkageSpec::Intrinsic;
+				bool isCopyFunc = ball.isCopyFunc;
+				bool existsUserDefinedCopyFunc = val.existsUserDefinedCopyFunc;
+				// only implicitly delete non-user defined functions that are  not intrinsic, and are
+				// not copy functions (assignment or copy constructor), unless a user-defined copy function exists.
+				// deleteStmt will be non-null only if a user-defined function is found.
+				if (isNotUserDefinedFunc && (! isCopyFunc || existsUserDefinedCopyFunc)) {
+					ball.decl.deleteStmt = val.deleteStmt;
 				}
+				out.push_back( ball.decl );
 			}
 		}
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/SynTree/Statement.cc	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -243,6 +243,6 @@
 }
 
-WhileStmt::WhileStmt( Expression *condition, Statement *body, bool isDoWhile ):
-	Statement(), condition( condition), body( body), isDoWhile( isDoWhile) {
+WhileStmt::WhileStmt( Expression *condition, Statement *body, std::list< Statement * > & initialization, bool isDoWhile ):
+	Statement(), condition( condition), body( body), initialization( initialization ), isDoWhile( isDoWhile) {
 }
 
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/SynTree/Statement.h	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -220,8 +220,9 @@
 	Expression *condition;
 	Statement *body;
+	std::list<Statement *> initialization;
 	bool isDoWhile;
 
 	WhileStmt( Expression *condition,
-	       Statement *body, bool isDoWhile = false );
+	       Statement *body, std::list<Statement *> & initialization, bool isDoWhile = false );
 	WhileStmt( const WhileStmt &other );
 	virtual ~WhileStmt();
Index: src/libcfa/concurrency/kernel.c
===================================================================
--- src/libcfa/concurrency/kernel.c	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/libcfa/concurrency/kernel.c	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -663,4 +663,5 @@
 	__cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this);
 
+	verify( ({int sval = 0; sem_getvalue(&this->idleLock, &sval); sval; }) < 65536);
 	sem_wait(&idleLock);
 
@@ -678,4 +679,5 @@
 	__cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this);
 	sem_post(&this->idleLock);
+	verify( ({int sval = 0; sem_getvalue(&this->idleLock, &sval); sval; }) < 65536);
 }
 
Index: src/tests/preempt_longrun/processor.c
===================================================================
--- src/tests/preempt_longrun/processor.c	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/tests/preempt_longrun/processor.c	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -23,3 +23,6 @@
 		p[pi] = new();
 	}
+	for ( int pi = 0; pi < 15; pi++ ) {
+		delete( p[pi] );
+	}
 }
Index: src/tests/raii/.expect/ctor-autogen-ERR1.txt
===================================================================
--- src/tests/raii/.expect/ctor-autogen-ERR1.txt	(revision 7d690958d55beb54cebdf7015660d074ebc40966)
+++ src/tests/raii/.expect/ctor-autogen-ERR1.txt	(revision f77dbc0dcbf73c4858565e6107fa1a519f2b4860)
@@ -1,9 +1,56 @@
-raii/ctor-autogen.c:102:1 error: No reasonable alternatives for expression Applying untyped: 
-  Name: ?{}
-...to: 
-  Cast of:
-    Variable Expression: x: instance of struct Managed with body 1 
-  ... to:
-    reference to instance of struct Managed with body 1 
-  constant expression (123 123: signed int)
+raii/ctor-autogen.c:102:1 error: Unique best alternative includes deleted identifier in Cast of:
+  Application of
+    Deleted Expression
+      Variable Expression: ?{}: static inline function
+      ... with parameters
+        _dst: reference to instance of struct Managed with body 1 
+        x: signed int
+      ... returning nothing 
 
+      ... deleted by: ?{}: function
+      ... with parameters
+        m: reference to instance of struct Managed with body 1 
+      ... returning nothing 
+      ... with body 
+        CompoundStmt
+          Expression Statement:
+            Application of
+              Variable Expression: ?=?: function
+              ... with parameters
+                intrinsic reference to signed int
+                intrinsic signed int
+              ... returning 
+                _retval__operator_assign: signed int
+                ... with attributes: 
+                  Attribute with name: unused
+
+
+            ... to arguments
+              Cast of:
+                Member Expression, with field: 
+                  x: signed int
+                ... from aggregate: 
+                  Cast of:
+                    Variable Expression: m: reference to instance of struct Managed with body 1 
+                  ... to:
+                    instance of struct Managed with body 1 
+              ... to:
+                reference to signed int
+              Cast of:
+                constant expression (0 0: zero_t)
+              ... to:
+                signed int
+
+            ... with environment:
+              Types:
+              Non-types:
+
+
+  ... to arguments
+    Cast of:
+      Variable Expression: x: instance of struct Managed with body 1 
+    ... to:
+      reference to instance of struct Managed with body 1 
+    constant expression (123 123: signed int)
+
+... to: nothing
