Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 113599)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -1085,7 +1085,9 @@
   FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
                                                    bool Complain,
                                                    DeclAccessPair &Found);
-  FunctionDecl *ResolveSingleFunctionTemplateSpecialization(Expr *From);
+  FunctionDecl *ResolveSingleFunctionTemplateSpecialization(Expr *From, 
+                                bool Complain = false,
+                                DeclAccessPair* Found = 0);
 
   Expr *FixOverloadedFunctionReference(Expr *E,
                                        DeclAccessPair FoundDecl,
@@ -3153,13 +3155,15 @@
                                                    FunctionTemplateDecl *FT2,
                                                    SourceLocation Loc,
                                            TemplatePartialOrderingContext TPOC);
+
   UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin,
                                            UnresolvedSetIterator SEnd,
                                            TemplatePartialOrderingContext TPOC,
                                            SourceLocation Loc,
                                            const PartialDiagnostic &NoneDiag,
                                            const PartialDiagnostic &AmbigDiag,
-                                        const PartialDiagnostic &CandidateDiag);
+                                        const PartialDiagnostic &CandidateDiag,
+                                        bool Complain = true);
 
   ClassTemplatePartialSpecializationDecl *
   getMoreSpecializedPartialSpecialization(
Index: lib/Sema/SemaCXXCast.cpp
===================================================================
--- lib/Sema/SemaCXXCast.cpp	(revision 113599)
+++ lib/Sema/SemaCXXCast.cpp	(working copy)
@@ -962,7 +962,17 @@
   InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExpr, 1);
   if (InitSeq.getKind() == InitializationSequence::FailedSequence && 
       (CStyle || !DestType->isReferenceType()))
+  {
+    // Even a cstyle cast can not convert (or reinterpret) a 
+    // name that can not be resolved
+    // do not allow - template<class T> void f(T);
+    // (void)((void (&)(int,char))f);
+    if (!(SrcExpr->getType() == Self.Context.OverloadTy && 
+      InitSeq.getFailureKind() == 
+        InitializationSequence::FK_AddressOfOverloadFailed))
+    
     return TC_NotApplicable;
+  }
     
   ExprResult Result
     = InitSeq.Perform(Self, Entity, InitKind, MultiExprArg(Self, &SrcExpr, 1));
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 113599)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -4962,7 +4962,17 @@
       // cv-unqualified type of the left operand.
       if (PerformImplicitConversion(rExpr, lhsType.getUnqualifiedType(),
                                     AA_Assigning))
+      {
+        if (rExpr->getType() == Context.OverloadTy)
+        {
+          
+          DeclAccessPair tmp;
+          // Call it again (initially was thru PerformImplict) but now Complain
+          ResolveAddressOfOverloadedFunction(rExpr, lhsType
+                                    , /* Complain */ true, tmp);
+        }
         return Incompatible;
+      }
       return Compatible;
     }
 
@@ -6771,9 +6781,26 @@
     resultType = Input->getType();
     if (resultType->isDependentType())
       break;
-    if (!resultType->isScalarType()) // C99 6.5.3.3p1
+    
+    if (!resultType->isScalarType())
+    {
       return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
         << resultType << Input->getSourceRange());
+    }
+    // ensure that it is convertible to bool
+    // i.e weed out '!&f' when &f is overloaded, but allow &f<int>
+    if (PerformContextuallyConvertToBool(Input)) // C99 6.5.3.3p1
+    {
+      if (resultType == Context.OverloadTy)
+      {
+        DeclAccessPair access;
+        // Call it again (initially was thru PerformContext) but now Complain
+        ResolveAddressOfOverloadedFunction(Input, Context.BoolTy, 
+              /* Complain */ true, access);
+        
+      }
+      return ExprError(); // Diagnostic is uttered above
+    }
     // LNot always has type int. C99 6.5.3.3p5.
     // In C++, it's bool. C++ 5.3.1p8
     resultType = getLangOptions().CPlusPlus ? Context.BoolTy : Context.IntTy;
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp	(revision 113599)
+++ lib/Sema/SemaInit.cpp	(working copy)
@@ -3154,11 +3154,22 @@
   //      conversions (Clause 4) will be used, if necessary, to convert the
   //      initializer expression to the cv-unqualified version of the 
   //      destination type; no user-defined conversions are considered.
+  
+  
   if (S.TryImplicitConversion(*this, Entity, Initializer,
                               /*SuppressUserConversions*/ true,
                               /*AllowExplicitConversions*/ false,
                               /*InOverloadResolution*/ false))
-    SetFailed(InitializationSequence::FK_ConversionFailed);
+  {
+    DeclAccessPair tmp;
+    // If this is an overloaded name, were we unable to resolve it ...
+    if (Initializer->getType() == S.Context.OverloadTy && 
+        !S.ResolveAddressOfOverloadedFunction(Initializer, Entity.getType(), 
+          false, tmp))
+      SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
+    else
+      SetFailed(InitializationSequence::FK_ConversionFailed);
+  }
   else
     setSequenceKind(StandardConversion);
 }
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp	(revision 113599)
+++ lib/Sema/SemaOverload.cpp	(working copy)
@@ -6180,6 +6180,21 @@
   return S.CheckUnresolvedMemberAccess(cast<UnresolvedMemberExpr>(E), D);
 }
 
+
+// Utter a diagnostic containing all the overloads, including templates
+static void NoteAllOverloadCandidates(Sema &S, const OverloadExpr* OvlExpr)
+{
+  for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
+                              E = OvlExpr->decls_end();   I != E; ++I)
+  {
+    if (FunctionTemplateDecl *FT = dyn_cast<FunctionTemplateDecl>((*I)->getUnderlyingDecl()))
+      S.NoteOverloadCandidate(FT->getTemplatedDecl());
+    else if (FunctionDecl *F = dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()))
+      S.NoteOverloadCandidate(F);
+  }
+    
+}
+
 /// ResolveAddressOfOverloadedFunction - Try to resolve the address of
 /// an overloaded function (C++ [over.over]), where @p From is an
 /// expression with overloaded function type and @p ToType is the type
@@ -6200,17 +6215,21 @@
                                          bool Complain,
                                          DeclAccessPair &FoundResult) {
   QualType FunctionType = ToType;
-  bool IsMember = false;
+  bool ToTypeIsInstanceMember = false;
   if (const PointerType *ToTypePtr = ToType->getAs<PointerType>())
     FunctionType = ToTypePtr->getPointeeType();
   else if (const ReferenceType *ToTypeRef = ToType->getAs<ReferenceType>())
     FunctionType = ToTypeRef->getPointeeType();
   else if (const MemberPointerType *MemTypePtr =
                     ToType->getAs<MemberPointerType>()) {
+    // strip out the class information i.e int (A::*)() becomes int (*)()
+    // C++ [over.over] p3
+    //   [...] the function type of the pointer to member is used to select 
+    //   the member function from the set of overloaded member functions
     FunctionType = MemTypePtr->getPointeeType();
-    IsMember = true;
+    ToTypeIsInstanceMember = true;
   }
-
+  
   // C++ [over.over]p1:
   //   [...] [Note: any redundant set of parentheses surrounding the
   //   overloaded function name is ignored (5.1). ]
@@ -6225,19 +6244,49 @@
   OverloadExpr::FindResult Ovl = OverloadExpr::find(From);
   OverloadExpr *OvlExpr = Ovl.Expression;
   
+  // template<class T> foo(T); &foo<int>; can only identify one function
+  // C++0x [temp.arg.explicit]p3:
+    //   [...] In contexts where deduction is done and fails, or in contexts
+    //   where deduction is not done, if a template argument list is 
+    //   specified and it, along with any default template arguments, 
+    //   identifies a single function template specialization, then the 
+    //   template-id is an lvalue for the function template specialization.
+  if (FunctionType->isBooleanType() && OvlExpr->hasExplicitTemplateArgs())
+  {
+    if (FunctionDecl* Fun = ResolveSingleFunctionTemplateSpecialization(From, 
+                                    Complain, &FoundResult) )
+    {
+      MarkDeclarationReferenced(From->getLocStart(), Fun);
+      if (Complain) {
+        CheckUnresolvedAccess(*this, OvlExpr, FoundResult);
+        DiagnoseUseOfDecl(FoundResult, OvlExpr->getNameLoc());
+      }
+      return Fun;
+    }
+    return 0;
+  }
+
   // We expect a pointer or reference to function, or a function pointer.
   FunctionType = Context.getCanonicalType(FunctionType).getUnqualifiedType();
   if (!FunctionType->isFunctionType()) {
     if (Complain)
-      Diag(From->getLocStart(), diag::err_addr_ovl_not_func_ptrref)
-        << OvlExpr->getName() << ToType;
-    
+    {
+      if (FunctionType->isBooleanType())
+      {
+        Diag(From->getLocStart(), diag::err_addr_ovl_ambiguous)
+          << OvlExpr->getName();
+        NoteAllOverloadCandidates(*this,OvlExpr);
+      }
+      else
+        Diag(From->getLocStart(), diag::err_addr_ovl_not_func_ptrref)
+          << OvlExpr->getName() << ToType;
+    }
     return 0;
   }
 
   // If the overload expression doesn't have the form of a pointer to
   // member, don't try to convert it to a pointer-to-member type.
-  if (IsMember && !Ovl.HasFormOfMemberPointer) {
+  if (ToTypeIsInstanceMember && !Ovl.HasFormOfMemberPointer) {
     if (!Complain) return 0;
 
     // TODO: Should we condition this on whether any functions might
@@ -6280,10 +6329,10 @@
             = dyn_cast<CXXMethodDecl>(FunctionTemplate->getTemplatedDecl())) {
         // Skip non-static function templates when converting to pointer, and
         // static when converting to member pointer.
-        if (Method->isStatic() == IsMember)
+        if (Method->isStatic() == ToTypeIsInstanceMember)
           continue;
-      } else if (IsMember)
-        continue;
+      } else if (ToTypeIsInstanceMember)
+        continue; // no point in checking non member candidates
 
       // C++ [over.over]p2:
       //   If the name is a function template, template argument deduction is
@@ -6314,13 +6363,13 @@
     if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
       // Skip non-static functions when converting to pointer, and static
       // when converting to member pointer.
-      if (Method->isStatic() == IsMember)
+      if (Method->isStatic() == ToTypeIsInstanceMember)
         continue;
       
       // If we have explicit template arguments, skip non-templates.
       if (OvlExpr->hasExplicitTemplateArgs())
         continue;
-    } else if (IsMember)
+    } else if (ToTypeIsInstanceMember) // ... then skip free function check
       continue;
 
     if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(Fn)) {
@@ -6339,12 +6388,8 @@
   if (Matches.empty()) {
     if (Complain) {
       Diag(From->getLocStart(), diag::err_addr_ovl_no_viable)
-        << OvlExpr->getName() << FunctionType;
-      for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
-                                 E = OvlExpr->decls_end(); 
-           I != E; ++I)
-        if (FunctionDecl *F = dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()))
-          NoteOverloadCandidate(F);
+        << OvlExpr->getName() << ToType;
+      NoteAllOverloadCandidates(*this, OvlExpr);
     }
     
     return 0;
@@ -6353,7 +6398,10 @@
     FoundResult = Matches[0].first;
     MarkDeclarationReferenced(From->getLocStart(), Result);
     if (Complain)
+    {
       CheckAddressOfMemberAccess(OvlExpr, Matches[0].first);
+      DiagnoseUseOfDecl(FoundResult, OvlExpr->getNameLoc());
+    }
     return Result;
   }
 
@@ -6382,7 +6430,7 @@
                            PDiag(diag::err_addr_ovl_ambiguous)
                                << Matches[0].second->getDeclName(),
                            PDiag(diag::note_ovl_candidate)
-                               << (unsigned) oc_function_template);
+                               << (unsigned) oc_function_template, Complain);
     assert(Result != MatchesCopy.end() && "no most-specialized template");
     MarkDeclarationReferenced(From->getLocStart(), *Result);
     FoundResult = Matches[Result - MatchesCopy.begin()].first;
@@ -6418,10 +6466,13 @@
 
   // FIXME: We should probably return the same thing that BestViableFunction
   // returns (even if we issue the diagnostics here).
-  Diag(From->getLocStart(), diag::err_addr_ovl_ambiguous)
-    << Matches[0].second->getDeclName();
-  for (unsigned I = 0, E = Matches.size(); I != E; ++I)
-    NoteOverloadCandidate(Matches[I].second);
+  if (Complain)
+  {
+    Diag(From->getLocStart(), diag::err_addr_ovl_ambiguous)
+      << Matches[0].second->getDeclName();
+    for (unsigned I = 0, E = Matches.size(); I != E; ++I)
+      NoteOverloadCandidate(Matches[I].second);
+  }
   return 0;
 }
 
@@ -6432,7 +6483,8 @@
 /// template, where that template-id refers to a single template whose template
 /// arguments are either provided by the template-id or have defaults, 
 /// as described in C++0x [temp.arg.explicit]p3.
-FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From) {
+FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From, 
+                    bool Complain, DeclAccessPair* FoundResult) {
   // C++ [over.over]p1:
   //   [...] [Note: any redundant set of parentheses surrounding the
   //   overloaded function name is ignored (5.1). ]
@@ -6484,9 +6536,22 @@
     
     // Multiple matches; we can't resolve to a single declaration.
     if (Matched)
+    {
+      if (FoundResult) *FoundResult = DeclAccessPair();
+      if (Complain)
+      {
+        Diag(From->getLocStart(), diag::err_addr_ovl_ambiguous)
+          << OvlExpr->getName();
+        NoteAllOverloadCandidates(*this, OvlExpr);
+      }
       return 0;
+    }
 
-    Matched = Specialization;
+    if ((Matched = Specialization) && FoundResult) // [sic] we want assignment here
+    {
+      *FoundResult = I.getPair();
+    }
+
   }
 
   return Matched;
Index: lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- lib/Sema/SemaTemplateDeduction.cpp	(revision 113599)
+++ lib/Sema/SemaTemplateDeduction.cpp	(working copy)
@@ -2339,9 +2339,10 @@
                          SourceLocation Loc,
                          const PartialDiagnostic &NoneDiag,
                          const PartialDiagnostic &AmbigDiag,
-                         const PartialDiagnostic &CandidateDiag) {
+                         const PartialDiagnostic &CandidateDiag,
+                         bool Complain) {
   if (SpecBegin == SpecEnd) {
-    Diag(Loc, NoneDiag);
+    if (Complain) Diag(Loc, NoneDiag);
     return SpecEnd;
   }
   
@@ -2387,13 +2388,14 @@
   }
   
   // Diagnose the ambiguity.
-  Diag(Loc, AmbigDiag);
+  if (Complain)  Diag(Loc, AmbigDiag);
   
   // FIXME: Can we order the candidates in some sane way?
-  for (UnresolvedSetIterator I = SpecBegin; I != SpecEnd; ++I)
-    Diag((*I)->getLocation(), CandidateDiag)
-      << getTemplateArgumentBindingsText(
-        cast<FunctionDecl>(*I)->getPrimaryTemplate()->getTemplateParameters(),
+  if (Complain)
+    for (UnresolvedSetIterator I = SpecBegin; I != SpecEnd; ++I)
+      Diag((*I)->getLocation(), CandidateDiag)
+        << getTemplateArgumentBindingsText(
+          cast<FunctionDecl>(*I)->getPrimaryTemplate()->getTemplateParameters(),
                     *cast<FunctionDecl>(*I)->getTemplateSpecializationArgs());
   
   return SpecEnd;
Index: test/CXX/expr/expr.unary/expr.unary.op/p4.cpp
===================================================================
--- test/CXX/expr/expr.unary/expr.unary.op/p4.cpp	(revision 113599)
+++ test/CXX/expr/expr.unary/expr.unary.op/p4.cpp	(working copy)
@@ -8,7 +8,7 @@
 
     void test() {
       // FIXME: this diagnostic is terrible
-      foo(&g<int>); // expected-error {{cannot initialize a parameter of type 'void (test0::A::*)(int)' with an rvalue of type '<overloaded function type>'}}
+      foo(&g<int>); // expected-error {{can't form member pointer of type 'void (test0::A::*)(int)' without '&' and class name}}
     }
   };
 }
@@ -40,6 +40,6 @@
 
   void A::test() {
     // FIXME: This diagnostic is terrible.
-    int (A::*ptr)(int) = &(A::foo); // expected-error {{cannot initialize a variable of type 'int (test2::A::*)(int)' with an rvalue of type '<overloaded function type>'}}
+    int (A::*ptr)(int) = &(A::foo); // expected-error{{can't form member pointer of type 'int (test2::A::*)(int)' without '&' and class name}}
   }
 }
Index: test/CXX/over/over.over/p2-explicit-args.cpp
===================================================================
--- test/CXX/over/over.over/p2-explicit-args.cpp	(revision 0)
+++ test/CXX/over/over.over/p2-explicit-args.cpp	(revision 0)
@@ -0,0 +1,313 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+
+/*
+// T = template
+// N = Normal, Non-template
+// I = Instance
+// S = Static
+*/
+
+template<class T> void only_T(T); //expected-note 10{{candidate}}
+
+void only_N(int);
+
+void two_NN(int);
+void two_NN(char, int);
+
+template<class T> void two_NT(T); //expected-note 2{{candidate}}
+void two_NT(int);                 //expected-note 2{{candidate}}
+
+template<class T> void two_T(T);
+template<class T> void two_T(T*);
+
+template<class T> void three_T(T);
+template<class T> void three_T(T*);
+template<class T> void three_T(T*,T);
+
+template<class T> void three_NNT(T);
+void three_NNT(int);
+void three_NNT(char);
+
+
+template<class T> void three_NTT(T);
+template<class T> void three_NTT(T*);
+void three_NTT(char);
+
+template<class T> void four_NNTT(T);
+template<class T> void four_NNTT(T*);
+void four_NNTT(int);
+void four_NNTT(char);
+
+void five_NNTTT(int); //expected-note {{candidate}}
+void five_NNTTT(char); //expected-note {{candidate}}
+template<class R, class T> R five_NNTTT(T);  //expected-note 2{{candidate}}
+template<class T> T five_NNTTT(T);    //expected-note 2{{candidate}}
+template<class T> T* five_NNTTT(T*);  //expected-note 2{{candidate}}
+
+
+
+template<typename T> T f0(T);
+int f0(int);
+
+struct S {
+  bool b1;
+  bool b2;
+  bool b3;
+};
+
+struct U {
+  template<class T> void only_T_I(T);         //expected-note 2{{candidate}}
+  template<class T> static void only_T_S(T*); //expected-note 2{{candidate}}
+
+  void only_N_I(int);
+  static void only_N_S(char);
+
+  void two_NN_IS(double);                 //expected-note 4{{candidate}}
+  static int two_NN_IS(int);              //expected-note 4{{candidate}}
+  
+  template<class T> void two_TT_IS(T);              //expected-note 2{{candidate}}
+  template<class T> static int two_TT_IS(int, T);   //expected-note 2{{candidate}}
+  
+  void two_NT_IS(int);
+  template<class T> static void two_NT_IS(T);
+
+  void three_NTT_III(U&);
+  template<class T> void three_NTT_III(T);
+  template<class R, class T> R three_NTT_III(T);
+
+  static void three_NTT_SSS(U*);
+  template<class T> static void three_NTT_SSS(T*);
+  template<class R, class T> static R* three_NTT_SSS(T*);
+
+  
+
+  void five_NNTTT_ISSSI(int);                      //expected-note{{candidate}}
+  template<class R, class T> R five_NNTTT_ISSSI(T); //expected-note{{candidate}}
+  static void five_NNTTT_ISSSI(char); //expected-note{{candidate}}
+  template<class T> static void five_NNTTT_ISSSI(T); //expected-note{{candidate}}
+  template<class T> static void five_NNTTT_ISSSI(T*); //expected-note{{candidate}}
+  
+
+};
+
+
+// -- an object or reference being initialized 
+void test_init() {
+  { bool b = &only_N; }
+  { bool b = only_N; }
+  { const bool& b = &only_N; }
+
+  { bool b = &only_T; } // expected-error{{address of overloaded function}}
+  { bool b = only_T; }         //expected-error{{address of overloaded function}}
+  { const bool& b = &only_T; } //expected-error{{address of overloaded function}}
+
+  { bool b = &only_T<int>; }        //ok
+  { bool b = only_T<int>; }         //ok
+  { const bool& b = only_T<int>; }  //ok
+
+
+
+  { bool b = &two_NT; }        //expected-error{{address of overloaded function}}
+  { bool b = only_T; }         //expected-error{{address of overloaded function }}
+  { const bool& b = &only_T; } //expected-error{{address of overloaded function }}
+
+
+  { int (*f)(int) = five_NNTTT; } //ok T (T)
+  { int* (*f)(int*) = five_NNTTT; } //ok T* (T*)
+  { int* (*f)(float*) = five_NNTTT; } //ok R (T)
+  { int (&f)(int) = five_NNTTT; } //ok T (T)
+  { int* (&f)(int*) = five_NNTTT; } //ok T* (T*)
+  { int* (&f)(float*) = five_NNTTT; } //ok R (T)
+  
+  { S s = { &only_N, &two_NT<int>, &three_NNT<int> }; }//ok
+  { S s = { only_N, two_NT<int>, three_NNT<int> }; }//ok
+
+  { S s = { &only_T, &two_NT<int>, &three_NNT<int> }; }//expected-error{{address of overloaded function}}
+  { S s = { only_T, two_NT<int>, three_NNT<int> }; }//expected-error{{address of overloaded function}}
+
+  { bool b = &U::only_N_I; }
+  { bool b = &U::only_N_S; }
+  { const bool& b = &U::only_T_S<int>; } 
+  { const bool& b = &U::only_T_I<int>; } 
+
+  { bool b = &U::only_T_I; } //expected-error{{address of overloaded function }}
+  { bool b = &U::only_T_S; } //expected-error{{address of overloaded function }}
+  { bool b = &U::two_NN_IS; } //expected-error{{address of overloaded function }}
+  { bool b = &(U::two_NN_IS); } //expected-error{{address of overloaded function }}
+  { const bool& b = &U::two_TT_IS<int>; } //expected-error{{address of overloaded function }}
+  
+
+  { void (*f)(int) = &U::five_NNTTT_ISSSI; } //ok T (T)
+  { int (U::*f)(int*) = &U::five_NNTTT_ISSSI; } //ok  R (T)
+  { void (U::*f)(int) = &(U::five_NNTTT_ISSSI); } //expected-error {{can't form member pointer}}
+  { void (*f)(int) = &(U::five_NNTTT_ISSSI); } //ok static void (T)
+
+}
+
+// -- the left side of an assignment (5.17),
+void test_assign_f0() {
+  bool b;
+  {  b = &only_N; }
+  {  b = only_N; }
+
+
+  {  b = &only_T; }        //expected-error{{address of overloaded function }} \
+                            // expected-error{{assigning to 'bool' from incompatible type }}
+  {  b = only_T; }         //expected-error{{address of overloaded function }} \
+                            // expected-error{{assigning to 'bool' from incompatible type }}
+  
+  {  b = &only_T<int>; }        //ok
+  {  b = only_T<int>; }         //ok
+
+
+
+
+  {  b = &two_NT; }        //expected-error{{address of overloaded function }} \
+                            // expected-error{{assigning to 'bool' from incompatible type }}
+  {  b = only_T; }         //expected-error{{address of overloaded function }} \
+                            // expected-error{{assigning to 'bool' from incompatible type }}
+
+
+
+  { int (*f)(int); f = five_NNTTT; } //ok T (T)
+  { int* (*f)(int*); f = five_NNTTT; } //ok T* (T*)
+  { int* (*f)(float*); f = five_NNTTT; } //ok R (T)
+  
+
+  {  b = &U::only_N_I; }
+  {  b = &U::only_N_S; }
+  {  b = &U::only_T_S<int>; } 
+  {  b = &U::only_T_I<int>; } 
+
+  {  b = &U::only_T_I; } //expected-error{{address of overloaded function }} \
+                            // expected-error{{assigning to 'bool' from incompatible type }}
+  {  b = &U::only_T_S; } //expected-error{{address of overloaded function }} \
+                            // expected-error{{assigning to 'bool' from incompatible type }}
+  {  b = &U::two_NN_IS; } //expected-error{{address of overloaded function }} \
+                            // expected-error{{assigning to 'bool' from incompatible type }}
+  {  b = &(U::two_NN_IS); } //expected-error{{address of overloaded function }} \
+                            // expected-error{{assigning to 'bool' from incompatible type }}
+  {  b = &U::two_TT_IS<int>; } //expected-error{{address of overloaded function }} \
+                            // expected-error{{assigning to 'bool' from incompatible type }}
+  
+
+  { void (*f)(int); f = &U::five_NNTTT_ISSSI; } //ok T (T)
+  { int (U::*f)(int*); f = &U::five_NNTTT_ISSSI; } //ok  R (T)
+  { void (U::*f)(int); f = &(U::five_NNTTT_ISSSI); } //expected-error {{can't form member pointer }} \
+                                        //expected-error {{assigning }}
+  { void (*f)(int); f = &(U::five_NNTTT_ISSSI); } //ok static void (T)
+}
+
+// -- a parameter of a function (5.2.2),
+void eat_f0(int a(int), float (*b)(float), int (&c)(int), float (&d)(float));
+template<class T> void deduce(T);   //expected-note 2{{candidate}}
+template<class R, class T> void deduce_f(R(T));
+void test_pass_f0() {
+  eat_f0(&five_NNTTT, &five_NNTTT, five_NNTTT, five_NNTTT);
+  deduce(two_NT<int>); // ok
+  deduce(two_NT); // expected-error {{no matching function}}
+  deduce(two_NN); // expected-error {{no matching function}}
+  deduce_f(two_NN); // ok - selects two_NN(int) over two_NN(int, char)
+}
+
+// -- a parameter of a user-defined operator (13.5),
+struct X { template<class R, class T> void operator+(R(T)); };  //expected-note 3{{candidate}}
+void operator+(X, int(int));    //expected-note {{candidate}}
+template<class T> void operator+(X&, T);  //expected-note 3{{candidate}}
+
+
+void test_operator_pass_f0(X x) {
+  x + &five_NNTTT;
+  x + &two_NT; // expected-error{{invalid operands}}
+
+  // FIXME: this should not be address of overloaded function - should match to the member operator which is clearly more specialized
+  // From C++0x
+  // temp.func.order p3
+  // [ Example:
+  // struct A { };
+  // template<class T> struct B {
+  //      template<class R> int operator*(R&); // #1
+  // };
+  // template<class T, class R> int operator*(T&, R&); // #2
+  // The declaration of B::operator* is transformed into the equivalent of
+  // template<class R> int operator*(B<A>&, R&); // #1a
+  // int main() {
+  //    A a;
+  //    B<A> b;
+  //    b * a; // calls #1a
+  // }
+  // —end example ]
+  x + &two_NT<int>; // expected-error {{use of overloaded operator}}
+  x + &five_NNTTT<int,char>; //expected-error {{use of overloaded operator}}
+  // -- End Fix Me 
+
+  x + &five_NNTTT<int,int>;  // ok --> +(X,int(int))
+  
+}
+
+// -- the return value of a function, operator function, or conversion (6.6.3),
+
+int (*test_return_1())(int) { return &five_NNTTT<int,int>; } // ok
+void (*test_return_2())(int) { return &U::two_NT_IS<int>; } // ok
+int (U::*test_return_3())(int) { return &U::five_NNTTT_ISSSI<int,int>; } //ok
+void (U::*test_return_4())(int) { return &U::two_NT_IS; } //ok
+void (*test_return_5())(double) { return &U::two_NT_IS; } //ok
+int (*test_return_6())(int, double) { return &U::two_TT_IS; } //ok
+
+
+struct C1
+{
+  typedef int (*f1)(int,double);
+  operator f1() const { return &U::two_TT_IS; }
+  template<class T> operator T&() const { return U::two_NT_IS<char>; }
+  template<class T> operator T*() const { return &five_NNTTT<int, char>; } //expected-error{{address of overloaded function }}
+
+  
+};
+
+int (*test_return_7)(int, double) = C1(); // ok operator f1()
+
+void (&test_return_9)(char) = C1(); // ok T&
+int (*test_return_10)(char) = C1(); // ok T*
+int (*test_return_8)(int) = C1(); //expected-note {{in instantiation of function template specialization }}
+
+// operator* returning a pointer to member
+template<class R, class T>
+T (R::*operator*(X, T (R::*)(T)))(T) //expected-note {{candidate template }}
+      { return &R::template five_NNTTT_ISSSI<T,T>; } // ok
+
+template<class R, class T> 
+T* (*operator*(R, T (*)(T)))(T**) //expected-note {{candidate template }}
+      { return &R::template three_NTT_SSS<T,T*>; } // ok
+
+
+void test_op()
+{
+  X() * &U::three_NTT_III<char,char>; //ok
+  U() * &U::three_NTT_SSS<char,char>; //ok
+  U() * &U::three_NTT_III<char,int>; // expected-error {{invalid operands}}
+}
+
+// -- an explicit type conversion (5.2.3, 5.2.9, 5.4), or
+void test_convert_f0() {
+  (void)((double (U::*)(int)) &U::five_NNTTT_ISSSI);
+  (void)((double (U::*)(int,char)) &U::five_NNTTT_ISSSI); //expected-error {{address of overloaded function}}
+  (void)((int (*)(int)) &U::two_NN_IS);
+  (void)((void (U::*)(double)) &U::two_NN_IS);
+  (void)((int (&)(int)) five_NNTTT);
+  (void)((int (&)(double)) five_NNTTT);
+  (void)((int (&)(double, char, int)) five_NNTTT); //expected-error {{address of overloaded function }}
+  
+}
+
+// -- a non-type template-parameter(14.3.2).
+template<int(int)> struct Y0 { };
+template<float(float)> struct Y1 { };
+template<int (&)(int)> struct Y2 { };
+template<float (&)(float)> struct Y3 { };
+
+Y0<five_NNTTT> y0;  //ok
+Y1<five_NNTTT> y0a;  //ok
+Y2<five_NNTTT> y2;  //ok
+Y3<five_NNTTT> y3;  //ok
Index: test/CXX/over/over.over/p2.cpp
===================================================================
--- test/CXX/over/over.over/p2.cpp	(revision 113599)
+++ test/CXX/over/over.over/p2.cpp	(working copy)
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-template<typename T> T f0(T, T);
+template<typename T> T f0(T, T); //expected-note {{candidate}}
 
 void test_f0() {
   int (*f0a)(int, int) = f0;
-  int (*f0b)(int, int) = &f0;
-  int (*f0c)(int, float) = f0; // expected-error{{cannot initialize}}
+  int (*f0b)(int, int) = &f0; 
+  int (*f0c)(int, float) = f0; //expected-error {{address of overloaded function 'f0'}}
   // FIXME: poor error message above!
 }
Index: test/CXX/over/over.over/p4.cpp
===================================================================
--- test/CXX/over/over.over/p4.cpp	(revision 113599)
+++ test/CXX/over/over.over/p4.cpp	(working copy)
@@ -17,7 +17,7 @@
 
 void test_f0_2() {
   using namespace N;
-  int (*fp0)(int) = f0; // expected-error{{ambiguous}} \ 
-                        // expected-error{{cannot initialize}}
+  int (*fp0)(int) = f0; // expected-error{{ambiguous}} 
+                        
   float (*fp1)(float) = f0;
 }
Index: test/SemaCXX/addr-of-overloaded-function.cpp
===================================================================
--- test/SemaCXX/addr-of-overloaded-function.cpp	(revision 113599)
+++ test/SemaCXX/addr-of-overloaded-function.cpp	(working copy)
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s 
-int f(double);
-int f(int);
+int f(double); //expected-note {{candidate}}
+int f(int); //expected-note {{candidate}}
 
 int (*pfd)(double) = f; // selects f(double)
 int (*pfd2)(double) = &f; // selects f(double)
@@ -9,7 +9,7 @@
 // FIXME: This error message is not very good. We need to keep better
 // track of what went wrong when the implicit conversion failed to
 // give a better error message here.
-int (*pfe)(...) = &f;    // expected-error{{cannot initialize a variable of type 'int (*)(...)' with an rvalue of type '<overloaded function type>'}}
+int (*pfe)(...) = &f;    // expected-error{{address of overloaded function}}
 int (&rfi)(int) = f;     // selects f(int)
 int (&rfd)(double) = f;  // selects f(double)
 
