Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision fba44f88c0909ebe9f84c63385f6fa1d508208a7)
+++ src/SymTab/Indexer.cc	(revision b16898e15cca72a9db8a280714dbc0100e4abffa)
@@ -21,4 +21,5 @@
 #include <unordered_set>
 #include <utility>
+#include <algorithm>
 
 #include "Mangler.h"
@@ -33,4 +34,6 @@
 #include "SynTree/Initializer.h"
 #include "SynTree/Statement.h"
+
+#include "InitTweak/InitTweak.h"
 
 #define debugPrint(x) if ( doDebug ) { std::cout << x; }
@@ -99,4 +102,66 @@
 
 		if ( --toFree->refCount == 0 ) delete toFree;
+	}
+
+	void Indexer::removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType * > & out ) const {
+		// only need to perform this step for constructors and destructors
+		if ( ! InitTweak::isCtorDtor( id ) ) return;
+
+		// helpful data structure
+		struct ValueType {
+			struct DeclBall {
+				FunctionDecl * decl;
+				bool isUserDefinedFunc; // properties for this particular decl
+				bool isDefaultFunc;
+				bool isCopyFunc;
+			};
+			// properties for this type
+			bool userDefinedFunc = false; // any user defined function found
+			bool userDefinedDefaultFunc = false; // user defined default ctor found
+			bool userDefinedCopyFunc = false; // user defined copy ctor found
+			std::list< DeclBall > decls;
+
+			// another FunctionDecl for the current type was found - determine
+			// if it has special properties and update data structure accordingly
+			ValueType & operator+=( FunctionDecl * function ) {
+				bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() );
+				bool isDefaultFunc = function->get_functionType()->get_parameters().size() == 1;
+				bool isCopyFunc = InitTweak::isCopyConstructor( function );
+				decls.push_back( DeclBall{ function, isUserDefinedFunc, isDefaultFunc, isCopyFunc } );
+				userDefinedFunc = userDefinedFunc || isUserDefinedFunc;
+				userDefinedDefaultFunc = userDefinedDefaultFunc || (isUserDefinedFunc && isDefaultFunc);
+				userDefinedCopyFunc = userDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc);
+				return *this;
+			}
+		}; // ValueType
+
+		std::list< DeclarationWithType * > copy;
+		copy.splice( copy.end(), out );
+
+		// organize discovered declarations by type
+		std::unordered_map< std::string, ValueType > funcMap;
+		for ( DeclarationWithType * decl : copy ) {
+			if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ) ) {
+				std::list< DeclarationWithType * > params = function->get_functionType()->get_parameters();
+				assert( ! params.empty() );
+				funcMap[ Mangler::mangle( params.front()->get_type() ) ] += function;
+			} else {
+				out.push_back( decl );
+			}
+		}
+
+		// if a type contains user defined ctor/dtors, then special rules trigger, which determine
+		// the set of ctor/dtors 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.
+		for ( std::pair< const std::string, ValueType > & pair : funcMap ) {
+			ValueType & val = pair.second;
+			for ( ValueType::DeclBall ball : val.decls ) {
+				if ( ! val.userDefinedFunc || ball.isUserDefinedFunc || (! val.userDefinedDefaultFunc && ball.isDefaultFunc) || (! val.userDefinedCopyFunc && ball.isCopyFunc) ) {
+					// decl conforms to the rules described above, so it should be seen by the requester
+					out.push_back( ball.decl );
+				}
+			}
+		}
 	}
 
@@ -461,4 +526,9 @@
 			searchTables = searchTables->base.tables;
 		}
+
+		// some special functions, e.g. constructors and destructors
+		// remove autogenerated functions when they are defined so that
+		// they can never be matched
+		removeSpecialOverrides( id, out );
 	}
 
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision fba44f88c0909ebe9f84c63385f6fa1d508208a7)
+++ src/SymTab/Indexer.h	(revision b16898e15cca72a9db8a280714dbc0100e4abffa)
@@ -128,4 +128,9 @@
 		static void deleteRef( Impl *toFree );
 
+		// Removes matching autogenerated constructors and destructors
+		// so that they will not be selected
+		// void removeSpecialOverrides( FunctionDecl *decl );
+		void removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType * > & out ) const;
+
 		/// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
 		void makeWritable();
