Bug 501549 - Unresolved symbol with lambda

Change-Id: Ic541e9a7ea4338aa0515705047f5fb614150d074
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
index 77519c5..e045a57 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
@@ -6060,6 +6060,34 @@
 		parseAndCheckBindings();
 	}
 
+	//	template<typename T>
+	//	T d();
+	//
+	//	template <typename U>
+	//	static decltype(&U::operator()) c(U* p);
+	//
+	//	template <typename F>
+	//	decltype(c<F>(d<F*>()))* waldo(F f);
+	//
+	//	template <typename T, typename U = decltype(&T::m)>
+	//	struct B {};
+	//
+	//	template <typename T, typename R, typename P>
+	//	struct B<T, R (*)(P)> {
+	//	  R operator()(P p);
+	//	};
+	//
+	//	struct A {
+	//	  static void m(int p);
+	//	};
+	//
+	//	void test() {
+	//	  waldo([]() { return B<A>(); }());
+	//	}
+	public void testTemplateArgumentDeductionWithFunctionSet_501549() throws Exception {
+		parseAndCheckBindings();
+	}
+
 	//	template<bool V, typename T>
 	//	struct C {
 	//	  typedef int s;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java
index 710b009..bc99123 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java
@@ -932,9 +932,33 @@
 							remaining.isRestrict());
 				}
 			} else if (p instanceof ICPPFunctionType) {
-				if (!(a instanceof ICPPFunctionType))
-					return false;
-				return fromFunctionType((ICPPFunctionType) p, (ICPPFunctionType) a, point);
+				ICPPFunctionType ftp = (ICPPFunctionType) p;
+				if (a instanceof ICPPFunctionType)
+					return fromFunctionType(ftp, (ICPPFunctionType) a, point);
+
+				if (a instanceof FunctionSetType) {
+					// 14.8.2.1-6 Handling of overloaded function sets.
+					CPPTemplateParameterMap success = null;
+					ICPPFunction[] fs= ((FunctionSetType) a).getFunctionSet().getBindings();
+					for (ICPPFunction f : fs) {
+						ICPPFunctionType fta = f.getType();
+						final CPPTemplateParameterMap saved = saveState();
+						try {
+							if (fromFunctionType(ftp, fta, point)) {
+								if (success != null)
+									return false;
+								success = saveState();
+							}
+						} finally {
+							restoreState(saved);
+						}
+					}
+					if (success != null) {
+						restoreState(success);
+						return true;
+					}
+				}
+				return false;
 			} else if (p instanceof ICPPTemplateParameter) {
 				ICPPTemplateArgument current=
 						fDeducedArgs.getArgument(((ICPPTemplateParameter) p).getParameterID(), fPackOffset);