Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 114784)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -2377,6 +2377,12 @@
 // C++ casts
 // These messages adhere to the TryCast pattern: %0 is an int specifying the
 // cast type, %1 is the source type, %2 is the destination type.
+def err_bad_reinterpret_cast_overload : Error<
+  "reinterpret_cast cannot resolve overloads: '%0'">;
+
+def err_bad_static_cast_overload : Error<
+  "address of overloaded function %0 cannot be static_cast to type %1">;
+
 def err_bad_cxx_cast_generic : Error<
   "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
   "functional-style cast}0 from %1 to %2 is not allowed">;
Index: lib/Sema/SemaCXXCast.cpp
===================================================================
--- lib/Sema/SemaCXXCast.cpp	(revision 114784)
+++ lib/Sema/SemaCXXCast.cpp	(working copy)
@@ -21,6 +21,9 @@
 #include <set>
 using namespace clang;
 
+
+static void NoteAllOverloadCandidates(Expr* const Expr, Sema& sema);
+
 enum TryCastResult {
   TC_NotApplicable, ///< The cast method is not applicable.
   TC_Success,       ///< The cast method is appropriate and successful.
@@ -37,6 +40,9 @@
   CT_Functional   ///< Type(expr)
 };
 
+
+
+
 static void CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                            const SourceRange &OpRange,
                            const SourceRange &DestRange);
@@ -465,8 +471,20 @@
   if (TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/false, OpRange,
                          msg, Kind)
       != TC_Success && msg != 0)
-    Self.Diag(OpRange.getBegin(), msg) << CT_Reinterpret
+  {
+    if (SrcExpr->getType() == Self.Context.OverloadTy)
+    {
+      //FIXME: &f<int>; is overloaded and resolvable 
+      Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload) 
+        << OverloadExpr::find(SrcExpr).Expression->getName() << OpRange;
+      NoteAllOverloadCandidates(SrcExpr, Self);
+
+    }
+    else
+      Self.Diag(OpRange.getBegin(), msg) << CT_Reinterpret
       << SrcExpr->getType() << DestType << OpRange;
+  }
+    
 }
 
 
@@ -491,8 +509,27 @@
   unsigned msg = diag::err_bad_cxx_cast_generic;
   if (TryStaticCast(Self, SrcExpr, DestType, /*CStyle*/false, OpRange, msg,
                     Kind, BasePath) != TC_Success && msg != 0)
-    Self.Diag(OpRange.getBegin(), msg) << CT_Static
+  {
+    if ( SrcExpr->getType() == Self.Context.OverloadTy )
+    {
+      OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression;
+      NestedNameSpecifier* nns = oe->getQualifier();
+      std::string oe_name;
+      if (nns)
+      {
+        llvm::raw_string_ostream os(oe_name);
+        nns->print(os,PrintingPolicy(Self.getLangOptions()));
+        os.flush();   
+      }
+      oe_name += oe->getName().getAsString();
+      Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)
+        << oe_name << DestType << OpRange;
+      NoteAllOverloadCandidates(SrcExpr, Self);
+    }
+    else
+      Self.Diag(OpRange.getBegin(), msg) << CT_Static
       << SrcExpr->getType() << DestType << OpRange;
+  }
   else if (Kind == CK_Unknown || Kind == CK_BitCast)
     Self.CheckCastAlign(SrcExpr, DestType, OpRange);
 }
@@ -951,17 +988,20 @@
     }
   }
   
-  // At this point of CheckStaticCast, if the destination is a reference,
-  // this has to work. There is no other way that works.
-  // On the other hand, if we're checking a C-style cast, we've still got
-  // the reinterpret_cast way.
   InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
   InitializationKind InitKind
     = InitializationKind::CreateCast(/*FIXME:*/OpRange, 
                                                                CStyle);    
   InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExpr, 1);
+
+  // At this point of CheckStaticCast, if the destination is a reference,
+  // or the expression is an overload expression this has to work. 
+  // There is no other way that works.
+  // On the other hand, if we're checking a C-style cast, we've still got
+  // the reinterpret_cast way.
+  
   if (InitSeq.getKind() == InitializationSequence::FailedSequence && 
-      (CStyle || !DestType->isReferenceType()))
+    (CStyle || !DestType->isReferenceType()))
     return TC_NotApplicable;
     
   ExprResult Result
@@ -1049,6 +1089,31 @@
   return TC_Success;
 }
 
+
+static void NoteAllOverloadCandidates(Expr* const Expr, Sema& sema)
+{
+  
+  assert(Expr->getType() == sema.Context.OverloadTy);
+
+  OverloadExpr::FindResult Ovl = OverloadExpr::find(Expr);
+  OverloadExpr *const OvlExpr = Ovl.Expression;
+
+  for (UnresolvedSetIterator it = OvlExpr->decls_begin(),
+    end = OvlExpr->decls_end(); it != end; ++it) {
+    if ( FunctionTemplateDecl *ftd = 
+              dyn_cast<FunctionTemplateDecl>((*it)->getUnderlyingDecl()) )
+    {
+	    sema.NoteOverloadCandidate(ftd->getTemplatedDecl());   
+    }
+    else if ( FunctionDecl *f = 
+                dyn_cast<FunctionDecl>((*it)->getUnderlyingDecl()) )
+    {
+      sema.NoteOverloadCandidate(f);
+    }
+  }
+}
+
+
 static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
                                         QualType DestType, bool CStyle,
                                         const SourceRange &OpRange,
@@ -1058,6 +1123,12 @@
   
   DestType = Self.Context.getCanonicalType(DestType);
   QualType SrcType = SrcExpr->getType();
+
+  // Is the source an overloaded name? (i.e. &foo)
+  // If so, reinterpret_cast can not help us here (13.4, p1, bullet 5)
+  if (SrcType == Self.Context.OverloadTy )
+    return TC_NotApplicable;
+
   if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {
     bool LValue = DestTypeTmp->isLValueReferenceType();
     if (LValue && SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
@@ -1073,6 +1144,7 @@
     // This code does this transformation for the checked types.
     DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());
     SrcType = Self.Context.getPointerType(SrcType);
+    
     IsLValueCast = true;
   }
 
@@ -1308,8 +1380,22 @@
   }
 
   if (tcr != TC_Success && msg != 0)
-    Diag(R.getBegin(), msg) << (FunctionalStyle ? CT_Functional : CT_CStyle)
-      << CastExpr->getType() << CastTy << R;
+  {
+    if (CastExpr->getType() == Context.OverloadTy)
+    {
+      DeclAccessPair Found;
+      FunctionDecl* Fn = ResolveAddressOfOverloadedFunction(CastExpr, 
+                                CastTy,
+                                /* Complain */ true,
+                                Found);
+      assert(!Fn && "cast failed but able to resolve overload expression!!");
+    }
+    else
+    {
+      Diag(R.getBegin(), msg) << (FunctionalStyle ? CT_Functional : CT_CStyle)
+        << CastExpr->getType() << CastTy << R;
+    }
+  }
   else if (Kind == CK_Unknown || Kind == CK_BitCast)
     CheckCastAlign(CastExpr, CastTy, R);
 
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp	(revision 114784)
+++ lib/Sema/SemaInit.cpp	(working copy)
@@ -3158,7 +3158,12 @@
                               /*SuppressUserConversions*/ true,
                               /*AllowExplicitConversions*/ false,
                               /*InOverloadResolution*/ false))
-    SetFailed(InitializationSequence::FK_ConversionFailed);
+  {
+    if (Initializer->getType() == Context.OverloadTy )
+      SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
+    else
+      SetFailed(InitializationSequence::FK_ConversionFailed);
+  }
   else
     setSequenceKind(StandardConversion);
 }
Index: test/SemaCXX/addr-of-overloaded-function-casting.cpp
===================================================================
--- test/SemaCXX/addr-of-overloaded-function-casting.cpp	(revision 0)
+++ test/SemaCXX/addr-of-overloaded-function-casting.cpp	(revision 0)
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+void g();
+
+void f();
+void f(int);
+
+template<class T> void t(T);
+template<class T> void t(T*);
+
+template<class T> void u(T);
+
+int main()
+{
+  //{ bool b = static_cast<void (&)(char)>(f); }
+  //bool b2 = !static_cast<void (*)(int)>(f); 
+  { bool b = (void (&)(char))f; } //error
+  { bool b = (void (*)(char))f; } //error
+  
+  { bool b = (void (&)(int))f; } //ok
+  { bool b = (void (*)(int))f; } //ok
+  
+  { bool b = static_cast<void (&)(char)>(f); } //error
+  { bool b = static_cast<void (*)(char)>(f); } //error
+  
+  { bool b = static_cast<void (&)(int)>(f); } //ok
+  { bool b = static_cast<void (*)(int)>(f); } //ok
+  
+  
+  { bool b = reinterpret_cast<void (&)(char)>(f); } //error
+  { bool b = reinterpret_cast<void (*)(char)>(f); } //error
+  
+  { bool b = reinterpret_cast<void (*)(char)>(g); } //ok
+  { bool b = static_cast<void (*)(char)>(g); } //error
+  
+  { bool b = reinterpret_cast<void (&)(int)>(f); } //error
+  { bool b = reinterpret_cast<void (*)(int)>(f); } //error
+
+  // -- now lets try templates
+  { bool b = (int (&)(char))t; } //error
+  { bool b = (int (*)(char))t; } //error
+  
+  { bool b = (void (&)(int))t; } //ok
+  { bool b = (void (*)(int))t; } //ok
+  
+  { bool b = static_cast<void (&)(char)>(t); } //ok
+  { bool b = static_cast<void (*)(char)>(t); } //ok
+  
+  { bool b = static_cast<void (&)(int)>(t); } //ok
+  { bool b = static_cast<void (*)(int)>(t); } //ok
+  
+  
+  { bool b = reinterpret_cast<void (&)(char)>(t); } //error
+  { bool b = reinterpret_cast<void (*)(char)>(t); } //error
+  
+  { bool b = reinterpret_cast<int (*)(char)>(g); } //ok
+  { bool b = static_cast<int (*)(char)>(t); } //error
+  { bool b = static_cast<int (&)(char)>(t); } //error
+  
+  { bool b = static_cast<void (&)(char)>(f); } //error
+  
+  
+  
+}
\ No newline at end of file
