Index: configure
===================================================================
--- configure	(revision 89faa82907bc300a63bff199051ce9533abffc68)
+++ configure	(revision 800bae1ceaef4edb966cdb57daf39b5e6e02c074)
@@ -796,4 +796,5 @@
 with_cfa_name
 with_target_hosts
+enable_gprofiler
 enable_dependency_tracking
 enable_shared
@@ -1455,4 +1456,5 @@
   --enable-silent-rules   less verbose build output (undo: "make V=1")
   --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-gprofiler     whether or not to enable gprofiler tools (if available)
   --enable-dependency-tracking
                           do not reject slow dependency extractors
@@ -3283,4 +3285,8 @@
 		\'--with-target-hosts=*) ;;
 
+		# skip gprofiler for libcfa
+		\'--enable-gprofiler=*) ;;
+		\'--disable-gprofiler) ;;
+
 		# append all other arguments to the sub configure arguments
 		*) LIBCFA_GENERAL_ARGS="${LIBCFA_GENERAL_ARGS} $var";;
@@ -3384,4 +3390,12 @@
 else
   target_hosts=${default_target}
+fi
+
+
+# Check whether --enable-gprofiler was given.
+if test "${enable_gprofiler+set}" = set; then :
+  enableval=$enable_gprofiler; enable_gprofiler=$enableval
+else
+  enable_gprofiler=yes
 fi
 
@@ -16704,5 +16718,5 @@
 fi
 
- if test "$HAVE_LIBPROFILER" -eq 1; then
+ if test "x$enable_gprofiler" = "xyes" -a "$HAVE_LIBPROFILER" -eq 1; then
   WITH_LIBPROFILER_TRUE=
   WITH_LIBPROFILER_FALSE='#'
@@ -16755,5 +16769,5 @@
 fi
 
- if test "$HAVE_LIBTCMALLOC" -eq 1; then
+ if test "x$enable_gprofiler" = "xyes" -a "$HAVE_LIBTCMALLOC" -eq 1; then
   WITH_LIBTCMALLOC_TRUE=
   WITH_LIBTCMALLOC_FALSE='#'
Index: configure.ac
===================================================================
--- configure.ac	(revision 89faa82907bc300a63bff199051ce9533abffc68)
+++ configure.ac	(revision 800bae1ceaef4edb966cdb57daf39b5e6e02c074)
@@ -94,4 +94,8 @@
 		# skip the target hosts
 		\'--with-target-hosts=*) ;;
+
+		# skip gprofiler for libcfa
+		\'--enable-gprofiler=*) ;;
+		\'--disable-gprofiler) ;;
 
 		# append all other arguments to the sub configure arguments
@@ -125,4 +129,8 @@
 	target_hosts=$withval, target_hosts=${default_target})
 
+AC_ARG_ENABLE(gprofiler,
+	[  --enable-gprofiler     whether or not to enable gprofiler tools (if available)],
+	enable_gprofiler=$enableval, enable_gprofiler=yes)
+
 AC_SUBST(TARGET_HOSTS, ${target_hosts})
 
@@ -192,8 +200,8 @@
 
 AC_CHECK_LIB([profiler], [ProfilingIsEnabledForAllThreads], [HAVE_LIBPROFILER=1], [HAVE_LIBPROFILER=0])
-AM_CONDITIONAL([WITH_LIBPROFILER], [test "$HAVE_LIBPROFILER" -eq 1])
+AM_CONDITIONAL([WITH_LIBPROFILER], [test "x$enable_gprofiler" = "xyes" -a "$HAVE_LIBPROFILER" -eq 1])
 
 AC_CHECK_LIB([tcmalloc], [malloc], [HAVE_LIBTCMALLOC=1], [HAVE_LIBTCMALLOC=0])
-AM_CONDITIONAL([WITH_LIBTCMALLOC], [test "$HAVE_LIBTCMALLOC" -eq 1])
+AM_CONDITIONAL([WITH_LIBTCMALLOC], [test "x$enable_gprofiler" = "xyes" -a "$HAVE_LIBTCMALLOC" -eq 1])
 
 # Checks for header files.
Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 89faa82907bc300a63bff199051ce9533abffc68)
+++ src/AST/Convert.cpp	(revision 800bae1ceaef4edb966cdb57daf39b5e6e02c074)
@@ -576,6 +576,6 @@
 		if ( srcInferred.mode == ast::Expr::InferUnion::Params ) {
 			const ast::InferredParams &srcParams = srcInferred.inferParams();
-			for (auto srcParam : srcParams) {
-				tgtInferParams[srcParam.first] = ParamEntry(
+			for (auto & srcParam : srcParams) {
+				auto res = tgtInferParams.emplace(srcParam.first, ParamEntry(
 					srcParam.second.decl,
 					get<Declaration>().accept1(srcParam.second.declptr),
@@ -583,5 +583,6 @@
 					get<Type>().accept1(srcParam.second.formalType),
 					get<Expression>().accept1(srcParam.second.expr)
-				);
+				));
+				assert(res.second);
 			}
 		} else if ( srcInferred.mode == ast::Expr::InferUnion::Slots  ) {
@@ -1982,5 +1983,5 @@
 		if ( !oldInferParams.empty() ) {
 			ast::InferredParams &tgt = newInferred.inferParams();
-			for (auto old : oldInferParams) {
+			for (auto & old : oldInferParams) {
 				tgt[old.first] = ast::ParamEntry(
 					old.second.decl,
Index: src/Common/Stats/Heap.cc
===================================================================
--- src/Common/Stats/Heap.cc	(revision 89faa82907bc300a63bff199051ce9533abffc68)
+++ src/Common/Stats/Heap.cc	(revision 800bae1ceaef4edb966cdb57daf39b5e6e02c074)
@@ -21,6 +21,14 @@
 #include <iostream>
 
-#if defined( NO_STATISTICS ) || defined( TCMALLOC )
-	#define NO_HEAP_STATISTICS
+#if defined(__has_feature)
+	#if __has_feature(address_sanitizer)
+		#define NO_HEAP_STATISTICS
+	# endif
+#endif
+
+#if defined( NO_STATISTICS ) || defined( TCMALLOC ) || defined(__SANITIZE_ADDRESS__)
+	#if !defined(NO_HEAP_STATISTICS)
+		#define NO_HEAP_STATISTICS
+	#endif
 #endif
 
Index: src/ResolvExpr/ResolveAssertions.cc
===================================================================
--- src/ResolvExpr/ResolveAssertions.cc	(revision 89faa82907bc300a63bff199051ce9533abffc68)
+++ src/ResolvExpr/ResolveAssertions.cc	(revision 800bae1ceaef4edb966cdb57daf39b5e6e02c074)
@@ -325,5 +325,6 @@
 					entry.second.expr = postmutate( entry.second.expr );
 					// xxx - look at entry.second.inferParams?
-					expr->inferParams[ entry.first ] = entry.second;
+					auto res = expr->inferParams.emplace( entry.first, entry.second );
+					assert(res.second);
 				}
 			}
Index: src/SynTree/ApplicationExpr.cc
===================================================================
--- src/SynTree/ApplicationExpr.cc	(revision 89faa82907bc300a63bff199051ce9533abffc68)
+++ src/SynTree/ApplicationExpr.cc	(revision 800bae1ceaef4edb966cdb57daf39b5e6e02c074)
@@ -28,18 +28,10 @@
 #include "Type.h"                // for Type, PointerType, FunctionType
 
+ParamEntry::ParamEntry( UniqueId decl, Declaration * declptr, Type * actualType, Type * formalType, Expression* expr )
+		: decl( decl ), declptr( declptr ), actualType( actualType ), formalType( formalType ), expr( expr ) {
+	}
+
 ParamEntry::ParamEntry( const ParamEntry &other ) :
-		decl( other.decl ), declptr( maybeClone( other.declptr ) ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) )/*, inferParams( new InferredParams( *other.inferParams ) )*/ {
-}
-
-ParamEntry &ParamEntry::operator=( const ParamEntry &other ) {
-	if ( &other == this ) return *this;
-	const_cast<UniqueId &>(decl) = other.decl;
-	const_cast<Declaration * &>(declptr) = maybeClone( other.declptr );
-	// xxx - this looks like a memory leak
-	const_cast<Type * &>(actualType) = maybeClone( other.actualType );
-	const_cast<Type * &>(formalType) = maybeClone( other.formalType );
-	expr = maybeClone( other.expr );
-	// *inferParams = *other.inferParams;
-	return *this;
+		decl( other.decl ), declptr( maybeClone( other.declptr ) ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ) {
 }
 
@@ -52,27 +44,14 @@
 
 ParamEntry::ParamEntry( ParamEntry && other ) :
-		decl( other.decl ), declptr( other.declptr ), actualType( other.actualType ), formalType( other.formalType ), expr( other.expr )/*, inferParams( std::move( other.inferParams ) )*/ {
-	const_cast<Declaration * &>(other.declptr) = nullptr;
-	const_cast<Type * &>(other.actualType) = nullptr;
-	const_cast<Type * &>(other.formalType) = nullptr;
-	other.expr = nullptr;
+		decl( other.decl ), declptr( other.declptr ), actualType( other.actualType ), formalType( other.formalType ), expr( other.expr ) {
+	new (&other) ParamEntry();
 }
 
 ParamEntry & ParamEntry::operator=( ParamEntry && other ) {
 	if ( &other == this ) return *this;
-	delete declptr;
-	delete actualType;
-	delete formalType;
-	delete expr;
-	const_cast<UniqueId &>(decl) = other.decl;
-	const_cast<Declaration * &>(declptr) = other.declptr;
-	const_cast<Type * &>(actualType) = other.actualType;
-	const_cast<Type * &>(formalType) = other.formalType;
-	expr = other.expr;
-	const_cast<Declaration * &>(other.declptr) = nullptr;
-	const_cast<Type * &>(other.actualType) = nullptr;
-	const_cast<Type * &>(other.formalType) = nullptr;
-	other.expr = nullptr;
-	// inferParams = std::move( other.inferParams );
+	this->~ParamEntry();
+	new (this) ParamEntry(other.decl, other.declptr, other.actualType, other.formalType, other.expr);
+	new (&other) ParamEntry();
+
 	return *this;
 }
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 89faa82907bc300a63bff199051ce9533abffc68)
+++ src/SynTree/Expression.h	(revision 800bae1ceaef4edb966cdb57daf39b5e6e02c074)
@@ -39,12 +39,9 @@
 /// but subject to decay-to-pointer and type parameter renaming
 struct ParamEntry {
-	ParamEntry(): decl( 0 ), declptr(nullptr), actualType( 0 ), formalType( 0 ), expr( 0 )/*, inferParams( new InferredParams )*/ {}
-	ParamEntry( UniqueId decl, Declaration * declptr, Type * actualType, Type * formalType, Expression* expr )
-		: decl( decl ), declptr( declptr ), actualType( actualType ), formalType( formalType ), expr( expr )/*, inferParams( new InferredParams )*/ {
-	}
+	ParamEntry(): decl( 0 ), declptr( nullptr ), actualType( nullptr ), formalType( nullptr ), expr( nullptr ) {}
+	ParamEntry( UniqueId decl, Declaration * declptr, Type * actualType, Type * formalType, Expression* expr );
 	ParamEntry( const ParamEntry & other );
 	ParamEntry( ParamEntry && other );
 	~ParamEntry();
-	ParamEntry & operator=( const ParamEntry & other );
 	ParamEntry & operator=( ParamEntry && other );
 
@@ -54,5 +51,4 @@
 	Type * const formalType;
 	Expression * expr;
-	// std::unique_ptr< InferredParams > inferParams;
 };
 
