Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 321a2481aec2e4a3da980c519cddd0b6e8fbf3ea)
+++ src/CodeGen/CodeGenerator.cc	(revision 64071c2ad8eac1915b692988a8dc0d8e9d7cb8da)
@@ -257,30 +257,9 @@
 				std::list< Expression* >::iterator arg = applicationExpr->get_args().begin();
 				switch ( opInfo.type ) {
-				  case OT_CTOR:
-				  case OT_DTOR:
-					{
-						// if the first argument's type is const then GCC complains. In this
-						// case, output an explicit ctor/dtor call and exit, rather than following
-						// the normal path
-						assert( arg != applicationExpr->get_args().end() );
-						assert( (*arg)->get_results().size() >= 1 );
-						Type * baseType = InitTweak::getPointerBase( (*arg)->get_results().front() );
-						if ( baseType->get_isConst() ) {
-							// cast away the qualifiers, to eliminate warnings
-							Type * newType = baseType->clone();
-							newType->get_qualifiers() = Type::Qualifiers();
-							*arg = new CastExpr( *arg, new PointerType( Type::Qualifiers(), newType ) );
-							varExpr->accept( *this );
-							output << "(";
-							genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
-							output << ")";
-							return;
-						}
-					}
-					// intentional fallthrough - instrinsic ctor/dtor for non-const objects should
-					// be handled the same way as assignment
 				  case OT_PREFIXASSIGN:
 				  case OT_POSTFIXASSIGN:
 				  case OT_INFIXASSIGN:
+				  case OT_CTOR:
+				  case OT_DTOR:
 					{
 						assert( arg != applicationExpr->get_args().end() );
@@ -324,8 +303,8 @@
 					if ( applicationExpr->get_args().size() == 1 ) {
 						// the expression fed into a single parameter constructor or destructor
-						// may contain side effects - output as a void expression
-						output << "((void)(";
+						// may contain side effects, so must still output this expression
+						output << "(";
 						(*arg++)->accept( *this );
-						output << ")) /* " << opInfo.inputName << " */";
+						output << ") /* " << opInfo.inputName << " */";
 					} else if ( applicationExpr->get_args().size() == 2 ) {
 						// intrinsic two parameter constructors are essentially bitwise assignment
@@ -409,8 +388,8 @@
 					if ( untypedExpr->get_args().size() == 1 ) {
 						// the expression fed into a single parameter constructor or destructor
-						// may contain side effects - output as a void expression
-						output << "((void)(";
+						// may contain side effects, so must still output this expression
+						output << "(";
 						(*arg++)->accept( *this );
-						output << ")) /* " << opInfo.inputName << " */";
+						output << ") /* " << opInfo.inputName << " */";
 					} else if ( untypedExpr->get_args().size() == 2 ) {
 						// intrinsic two parameter constructors are essentially bitwise assignment
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 321a2481aec2e4a3da980c519cddd0b6e8fbf3ea)
+++ src/InitTweak/InitTweak.cc	(revision 64071c2ad8eac1915b692988a8dc0d8e9d7cb8da)
@@ -7,144 +7,148 @@
 
 namespace InitTweak {
-  namespace {
-    class HasDesignations : public Visitor {
-    public:
-      bool hasDesignations = false;
-      template<typename Init>
-      void handleInit( Init * init ) {
-        if ( ! init->get_designators().empty() ) hasDesignations = true;
-        else Visitor::visit( init );
-      }
-      virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); }
-      virtual void visit( ListInit * listInit ) { handleInit( listInit); }
-    };
+	namespace {
+		class HasDesignations : public Visitor {
+		public:
+			bool hasDesignations = false;
+			template<typename Init>
+			void handleInit( Init * init ) {
+				if ( ! init->get_designators().empty() ) hasDesignations = true;
+				else Visitor::visit( init );
+			}
+			virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); }
+			virtual void visit( ListInit * listInit ) { handleInit( listInit); }
+		};
 
-    class InitExpander : public Visitor {
-      public:
-      InitExpander() {}
-      virtual void visit( SingleInit * singleInit );
-      virtual void visit( ListInit * listInit );
-      std::list< Expression * > argList;
-    };
+		class InitExpander : public Visitor {
+			public:
+			InitExpander() {}
+			virtual void visit( SingleInit * singleInit );
+			virtual void visit( ListInit * listInit );
+			std::list< Expression * > argList;
+		};
 
-    void InitExpander::visit( SingleInit * singleInit ) {
-      argList.push_back( singleInit->get_value()->clone() );
-    }
+		void InitExpander::visit( SingleInit * singleInit ) {
+			argList.push_back( singleInit->get_value()->clone() );
+		}
 
-    void InitExpander::visit( ListInit * listInit ) {
-      // xxx - for now, assume no nested list inits
-      std::list<Initializer*>::iterator it = listInit->begin_initializers();
-      for ( ; it != listInit->end_initializers(); ++it ) {
-        (*it)->accept( *this );
-      }
-    }
-  }
+		void InitExpander::visit( ListInit * listInit ) {
+			// xxx - for now, assume no nested list inits
+			std::list<Initializer*>::iterator it = listInit->begin_initializers();
+			for ( ; it != listInit->end_initializers(); ++it ) {
+				(*it)->accept( *this );
+			}
+		}
+	}
 
-  std::list< Expression * > makeInitList( Initializer * init ) {
-    InitExpander expander;
-    maybeAccept( init, expander );
-    return expander.argList;
-  }
+	std::list< Expression * > makeInitList( Initializer * init ) {
+		InitExpander expander;
+		maybeAccept( init, expander );
+		return expander.argList;
+	}
 
-  bool isDesignated( Initializer * init ) {
-    HasDesignations finder;
-    maybeAccept( init, finder );
-    return finder.hasDesignations;
-  }
+	bool isDesignated( Initializer * init ) {
+		HasDesignations finder;
+		maybeAccept( init, finder );
+		return finder.hasDesignations;
+	}
 
-  bool tryConstruct( ObjectDecl * objDecl ) {
-    return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
-      (objDecl->get_init() == NULL ||
-        ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) &&
-      ! isDesignated( objDecl->get_init() );
-  }
+	bool tryConstruct( ObjectDecl * objDecl ) {
+		return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
+			(objDecl->get_init() == NULL ||
+				( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) &&
+			! isDesignated( objDecl->get_init() );
+	}
 
-  Expression * getCtorDtorCall( Statement * stmt ) {
-    if ( stmt == NULL ) return NULL;
-    if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
-      return exprStmt->get_expr();
-    } else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) {
-      // could also be a compound statement with a loop, in the case of an array
-      assert( compoundStmt->get_kids().size() == 2 ); // loop variable and loop
-      ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() );
-      assert( forStmt && forStmt->get_body() );
-      return getCtorDtorCall( forStmt->get_body() );
-    } if ( ImplicitCtorDtorStmt * impCtorDtorStmt = dynamic_cast< ImplicitCtorDtorStmt * > ( stmt ) ) {
-      return getCtorDtorCall( impCtorDtorStmt->get_callStmt() );
-    } else {
-      // should never get here
-      assert( false && "encountered unknown call statement" );
-    }
-  }
+	Expression * getCtorDtorCall( Statement * stmt ) {
+		if ( stmt == NULL ) return NULL;
+		if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
+			return exprStmt->get_expr();
+		} else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) {
+			// could also be a compound statement with a loop, in the case of an array
+			assert( compoundStmt->get_kids().size() == 2 ); // loop variable and loop
+			ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() );
+			assert( forStmt && forStmt->get_body() );
+			return getCtorDtorCall( forStmt->get_body() );
+		} if ( ImplicitCtorDtorStmt * impCtorDtorStmt = dynamic_cast< ImplicitCtorDtorStmt * > ( stmt ) ) {
+			return getCtorDtorCall( impCtorDtorStmt->get_callStmt() );
+		} else {
+			// should never get here
+			assert( false && "encountered unknown call statement" );
+		}
+	}
 
-  bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
-    Expression * callExpr = getCtorDtorCall( stmt );
-    if ( ! callExpr ) return false;
-    ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr );
-    assert( appExpr );
-    VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
-    assert( function );
-    // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
-    // will call all member dtors, and some members may have a user defined dtor.
-    FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() );
-    assert( funcType );
-    return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1;
-  }
+	bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
+		Expression * callExpr = getCtorDtorCall( stmt );
+		if ( ! callExpr ) return false;
+		ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr );
+		assert( appExpr );
+		VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
+		assert( function );
+		// check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
+		// will call all member dtors, and some members may have a user defined dtor.
+		FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() );
+		assert( funcType );
+		return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1;
+	}
 
-  namespace {
-    template<typename CallExpr>
-    Expression * callArg( CallExpr * callExpr, unsigned int pos ) {
-      if ( pos >= callExpr->get_args().size() ) assert( false && "asking for argument that doesn't exist. Return NULL/throw exception?" );
-      for ( Expression * arg : callExpr->get_args() ) {
-        if ( pos == 0 ) return arg;
-        pos--;
-      }
-      assert( false );
-    }
-  }
+	namespace {
+		template<typename CallExpr>
+		Expression *& callArg( CallExpr * callExpr, unsigned int pos ) {
+			if ( pos >= callExpr->get_args().size() ) assert( false && "asking for argument that doesn't exist. Return NULL/throw exception?" );
+			for ( Expression *& arg : callExpr->get_args() ) {
+				if ( pos == 0 ) return arg;
+				pos--;
+			}
+			assert( false );
+		}
+	}
 
-  Expression * getCallArg( Expression * callExpr, unsigned int pos ) {
-    if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr ) ) {
-      return callArg( appExpr, pos );
-    } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( callExpr ) ) {
-      return callArg( untypedExpr, pos );
-    } else {
-      assert( false && "Unexpected expression type passed to getCallArg" );
-    }
-  }
+	Expression *& getCallArg( Expression * callExpr, unsigned int pos ) {
+		if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr ) ) {
+			return callArg( appExpr, pos );
+		} else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( callExpr ) ) {
+			return callArg( untypedExpr, pos );
+		} else {
+			assert( false && "Unexpected expression type passed to getCallArg" );
+		}
+	}
 
-  namespace {
-    template<typename CallExpr>
-    std::string funcName( CallExpr * expr ) {
-      Expression * func = expr->get_function();
-      if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( func ) ) {
-        return nameExpr->get_name();
-      } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( func ) ) {
-        return varExpr->get_var()->get_name();
-      } else {
-        assert( false && "Unexpected expression type being called as a function in call expression" );
-      }
-    }
-  }
+	namespace {
+		template<typename CallExpr>
+		std::string funcName( CallExpr * expr ) {
+			Expression * func = expr->get_function();
+			if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( func ) ) {
+				return nameExpr->get_name();
+			} else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( func ) ) {
+				return varExpr->get_var()->get_name();
+			} else {
+				assert( false && "Unexpected expression type being called as a function in call expression" );
+			}
+		}
+	}
 
-  std::string getFunctionName( Expression * expr ) {
-    if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr ) ) {
-      return funcName( appExpr );
-    } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * > ( expr ) ) {
-      return funcName( untypedExpr );
-    } else {
-      assert( false && "Unexpected expression type passed to getFunctionName" );
-    }
-  }
+	std::string getFunctionName( Expression * expr ) {
+		if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr ) ) {
+			return funcName( appExpr );
+		} else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * > ( expr ) ) {
+			return funcName( untypedExpr );
+		} else {
+			assert( false && "Unexpected expression type passed to getFunctionName" );
+		}
+	}
 
-  Type * getPointerBase( Type * type ) {
-    if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) {
-      return ptrType->get_base();
-    } else if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
-      return arrayType->get_base();
-    } else {
-      return NULL;
-    }
-  }
+	Type * getPointerBase( Type * type ) {
+		if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) {
+			return ptrType->get_base();
+		} else if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
+			return arrayType->get_base();
+		} else {
+			return NULL;
+		}
+	}
 
+	Type * isPointerType( Type * type ) {
+		if ( getPointerBase( type ) ) return type;
+		else return NULL;
+	}
 }
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision 321a2481aec2e4a3da980c519cddd0b6e8fbf3ea)
+++ src/InitTweak/InitTweak.h	(revision 64071c2ad8eac1915b692988a8dc0d8e9d7cb8da)
@@ -47,8 +47,11 @@
 
   /// returns the argument to a call expression in position N indexed from 0
-  Expression * getCallArg( Expression * callExpr, unsigned int pos );
+  Expression *& getCallArg( Expression * callExpr, unsigned int pos );
 
-  /// returns the base type of a PointerType or ArrayType
+  /// returns the base type of a PointerType or ArrayType, else returns NULL
   Type * getPointerBase( Type * );
+
+  /// returns the argument if it is a PointerType or ArrayType, else returns NULL
+  Type * isPointerType( Type * );
 } // namespace
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 321a2481aec2e4a3da980c519cddd0b6e8fbf3ea)
+++ src/ResolvExpr/Resolver.cc	(revision 64071c2ad8eac1915b692988a8dc0d8e9d7cb8da)
@@ -516,13 +516,13 @@
 
 	void Resolver::visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) {
-		// this code is fairly gross. If VariableExpr didn't have its own results list then this could be cleaned up a bit
-		// by remembering the ObjectDecl in the ImplicitCtorDtorStmt and changing the ObjectDecl's type temporarily, but currently
-		// VariableExprs have their own type list which is manipulated in AlternativeFinder (e.g. in inferRecursive).
-
-		// before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed)
+		// before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed).
+		// Do this through a cast expression to greatly simplify the code.
 		Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );
 		assert( callExpr );
-		Expression * constructee = InitTweak::getCallArg( callExpr, 0 );
+		Expression *& constructee = InitTweak::getCallArg( callExpr, 0 );
 		Type * type = 0;
+
+		// need to find the type of the first argument, which is unfortunately not uniform since array construction
+		// includes an untyped '+' expression.
 		if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) {
 			// constructee is <array>+<index>
@@ -531,6 +531,5 @@
 			assert( dynamic_cast< VariableExpr * >( arr ) );
 			assert( arr && arr->get_results().size() == 1 );
-			type = InitTweak::getPointerBase( arr->get_results().front() );
-			assert( type );
+			type = arr->get_results().front()->clone();
 		} else {
 			// otherwise, constructing a plain object, which means the object's address is being taken.
@@ -539,50 +538,21 @@
 			assert( constructee->get_results().size() == 1 );
 			AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
-			assert( addrExpr );
-			VariableExpr * varExpr = dynamic_cast< VariableExpr * >( addrExpr->get_arg() );
-			assert( varExpr && varExpr->get_results().size() == 1 );
-			type = varExpr->get_results().front();
-		}
-		// remember qualifiers so they can be replaced
-		Type::Qualifiers qualifiers = type->get_qualifiers();
-
+			assert( addrExpr && addrExpr->get_results().size() == 1);
+			type = addrExpr->get_results().front()->clone();
+		}
+		// cast to T* with qualifiers removed.
 		// unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
 		// must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
 		// remove lvalue as a qualifier, this can change to
 		//   type->get_qualifiers() = Type::Qualifiers();
-		type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
+		Type * base = InitTweak::getPointerBase( type );
+		assert( base );
+		base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
+		// if pointer has lvalue qualifier, cast won't appear in output
+		type->set_isLvalue( false );
+		constructee = new CastExpr( constructee, type );
 
 		// finally, resolve the ctor/dtor
 		impCtorDtorStmt->get_callStmt()->accept( *this );
-
-		// reset type qualifiers, but first need to figure out where everything is again
-		// because the expressions are often changed by the resolver.
-		callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );
-		assert( callExpr );
-		constructee = InitTweak::getCallArg( callExpr, 0 );
-		if ( ApplicationExpr * plusExpr = dynamic_cast< ApplicationExpr * >( constructee ) ) {
-			// constructee is <array>+<index>
-			// get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed
-			Expression * arr = InitTweak::getCallArg( plusExpr, 0 );
-			assert( dynamic_cast< VariableExpr * >( arr ) );
-			assert( arr && arr->get_results().size() == 1 );
-			type = InitTweak::getPointerBase( arr->get_results().front() );
-			assert( type );
-			type->get_qualifiers() = qualifiers;
-		} else {
-			// otherwise constructing a plain object
-			// replace qualifiers on AddressExpr and on inner VariableExpr
-			assert( constructee->get_results().size() == 1 );
-			AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
-			assert( addrExpr );
-			type = InitTweak::getPointerBase( addrExpr->get_results().front() );
-			assert( type );
-			type->get_qualifiers() = qualifiers;
-
-			VariableExpr * varExpr = dynamic_cast< VariableExpr * >( addrExpr->get_arg() );
-			assert( varExpr && varExpr->get_results().size() == 1 );
-			type = varExpr->get_results().front();
-			type->get_qualifiers() = qualifiers;
-		}
 	}
 } // namespace ResolvExpr
