diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index f30e809..c2d6de7 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2239,8 +2239,6 @@
 
 /// \brief Try a reference initialization that involves calling a conversion
 /// function.
-///
-/// FIXME: look intos DRs 656, 896
 static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
                                              const InitializedEntity &Entity,
                                              const InitializationKind &Kind,
@@ -2331,7 +2329,7 @@
       if (ConvTemplate)
         Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
       else
-        Conv = cast<CXXConversionDecl>(*I);
+        Conv = cast<CXXConversionDecl>(D);
       
       // If the conversion function doesn't return a reference type,
       // it can't be considered for this conversion unless we're allowed to
@@ -2401,14 +2399,14 @@
   return OR_Success;
 }
   
-/// \brief Attempt reference initialization (C++0x [dcl.init.list]) 
+/// \brief Attempt reference initialization (C++0x [dcl.init.ref]) 
 static void TryReferenceInitialization(Sema &S, 
                                        const InitializedEntity &Entity,
                                        const InitializationKind &Kind,
                                        Expr *Initializer,
                                        InitializationSequence &Sequence) {
   Sequence.setSequenceKind(InitializationSequence::ReferenceBinding);
-  
+
   QualType DestType = Entity.getType();
   QualType cv1T1 = DestType->getAs<ReferenceType>()->getPointeeType();
   Qualifiers T1Quals;
@@ -2417,7 +2415,7 @@
   Qualifiers T2Quals;
   QualType T2 = S.Context.getUnqualifiedArrayType(cv2T2, T2Quals);
   SourceLocation DeclLoc = Initializer->getLocStart();
-  
+
   // If the initializer is the address of an overloaded function, try
   // to resolve the overloaded function. If all goes well, T2 is the
   // type of the resulting function.
@@ -2431,29 +2429,33 @@
       Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
       return;
     }
-    
+
     Sequence.AddAddressOverloadResolutionStep(Fn, Found);
     cv2T2 = Fn->getType();
     T2 = cv2T2.getUnqualifiedType();
   }
-  
+
   // Compute some basic properties of the types and the initializer.
   bool isLValueRef = DestType->isLValueReferenceType();
   bool isRValueRef = !isLValueRef;
   bool DerivedToBase = false;
-  Expr::isLvalueResult InitLvalue = Initializer->isLvalue(S.Context);
+  Expr::Classification InitCategory = Initializer->Classify(S.Context);
   Sema::ReferenceCompareResult RefRelationship
     = S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2, DerivedToBase);
-  
+
   // C++0x [dcl.init.ref]p5:
   //   A reference to type "cv1 T1" is initialized by an expression of type 
   //   "cv2 T2" as follows:
   //
   //     - If the reference is an lvalue reference and the initializer 
   //       expression
+  // Note the analogous bullet points for rvlaue refs to functions. Because
+  // there are no function rvalues in C++, rvalue refs to functions are treated
+  // like lvalue refs.
   OverloadingResult ConvOvlResult = OR_Success;
-  if (isLValueRef) {
-    if (InitLvalue == Expr::LV_Valid && 
+  bool T1Function = T1->isFunctionType();
+  if (isLValueRef || T1Function) {
+    if (InitCategory.isLValue() && 
         RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
       //   - is an lvalue (but is not a bit-field), and "cv1 T1" is 
       //     reference-compatible with "cv2 T2," or
@@ -2481,10 +2483,13 @@
     //       with "cv3 T3" (this conversion is selected by enumerating the 
     //       applicable conversion functions (13.3.1.6) and choosing the best
     //       one through overload resolution (13.3)),
-    if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType()) {
+    // If we have an rvalue ref to function type here, the rhs must be
+    // an rvalue.
+    if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() &&
+        (isLValueRef || InitCategory.isRValue())) {
       ConvOvlResult = TryRefInitWithConversionFunction(S, Entity, Kind, 
                                                        Initializer,
-                                                       /*AllowRValues=*/false,
+                                                   /*AllowRValues=*/isRValueRef,
                                                        Sequence);
       if (ConvOvlResult == OR_Success)
         return;
@@ -2495,19 +2500,20 @@
       }
     }
   }
-  
+
   //     - Otherwise, the reference shall be an lvalue reference to a 
   //       non-volatile const type (i.e., cv1 shall be const), or the reference
   //       shall be an rvalue reference and the initializer expression shall 
-  //       be an rvalue.
+  //       be an rvalue or have a function type.
+  // We handled the function type stuff above.
   if (!((isLValueRef && T1Quals.hasConst() && !T1Quals.hasVolatile()) ||
-        (isRValueRef && InitLvalue != Expr::LV_Valid))) {
+        (isRValueRef && InitCategory.isRValue()))) {
     if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
       Sequence.SetOverloadFailure(
                         InitializationSequence::FK_ReferenceInitOverloadFailed,
                                   ConvOvlResult);
     else if (isLValueRef)
-      Sequence.SetFailed(InitLvalue == Expr::LV_Valid
+      Sequence.SetFailed(InitCategory.isLValue()
         ? (RefRelationship == Sema::Ref_Related
              ? InitializationSequence::FK_ReferenceInitDropsQualifiers
              : InitializationSequence::FK_NonConstLValueReferenceBindingToUnrelated)
@@ -2515,15 +2521,15 @@
     else
       Sequence.SetFailed(
                     InitializationSequence::FK_RValueReferenceBindingToLValue);
-    
+
     return;
   }
-  
-  //       - If T1 and T2 are class types and
-  if (T1->isRecordType() && T2->isRecordType()) {
+
+  //       - [If T1 is not a function type], if T2 is a class type and
+  if (!T1Function && T2->isRecordType()) {
     //       - the initializer expression is an rvalue and "cv1 T1" is 
     //         reference-compatible with "cv2 T2", or
-    if (InitLvalue != Expr::LV_Valid && 
+    if (InitCategory.isRValue() && 
         RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
       // The corresponding bullet in C++03 [dcl.init.ref]p5 gives the
       // compiler the freedom to perform a copy here or bind to the
@@ -2546,7 +2552,7 @@
       Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
       return;
     }
-    
+
     //       - T1 is not reference-related to T2 and the initializer expression
     //         can be implicitly converted to an rvalue of type "cv3 T3" (this
     //         conversion is selected by enumerating the applicable conversion
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 56e8005..344fb92 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2622,6 +2622,93 @@
     return Ref_Related;
 }
 
+/// \brief Look for a user-defined conversion to an lvalue reference-compatible
+///        with DeclType. Return true if something definite is found.
+static bool
+FindConversionToLValue(Sema &S, ImplicitConversionSequence &ICS,
+                       QualType DeclType, SourceLocation DeclLoc,
+                       Expr *Init, QualType T2, bool AllowExplicit) {
+  assert(T2->isRecordType() && "Can only find conversions of record types.");
+  CXXRecordDecl *T2RecordDecl
+    = dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
+
+  OverloadCandidateSet CandidateSet(DeclLoc);
+  const UnresolvedSetImpl *Conversions
+    = T2RecordDecl->getVisibleConversionFunctions();
+  for (UnresolvedSetImpl::iterator I = Conversions->begin(),
+         E = Conversions->end(); I != E; ++I) {
+    NamedDecl *D = *I;
+    CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
+    if (isa<UsingShadowDecl>(D))
+      D = cast<UsingShadowDecl>(D)->getTargetDecl();
+
+    FunctionTemplateDecl *ConvTemplate
+      = dyn_cast<FunctionTemplateDecl>(D);
+    CXXConversionDecl *Conv;
+    if (ConvTemplate)
+      Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
+    else
+      Conv = cast<CXXConversionDecl>(D);
+
+    // If the conversion function doesn't return a reference type,
+    // it can't be considered for this conversion. An rvalue reference
+    // is only acceptable if its referencee is a function type.
+    const ReferenceType *RefType =
+      Conv->getConversionType()->getAs<ReferenceType>();
+    if (RefType && (RefType->isLValueReferenceType() ||
+                    RefType->getPointeeType()->isFunctionType()) &&
+        (AllowExplicit || !Conv->isExplicit())) {
+      if (ConvTemplate)
+        S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
+                                       Init, DeclType, CandidateSet);
+      else
+        S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init,
+                               DeclType, CandidateSet);
+    }
+  }
+
+  OverloadCandidateSet::iterator Best;
+  switch (S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+  case OR_Success:
+    // C++ [over.ics.ref]p1:
+    //
+    //   [...] If the parameter binds directly to the result of
+    //   applying a conversion function to the argument
+    //   expression, the implicit conversion sequence is a
+    //   user-defined conversion sequence (13.3.3.1.2), with the
+    //   second standard conversion sequence either an identity
+    //   conversion or, if the conversion function returns an
+    //   entity of a type that is a derived class of the parameter
+    //   type, a derived-to-base Conversion.
+    if (!Best->FinalConversion.DirectBinding)
+      return false;
+
+    ICS.setUserDefined();
+    ICS.UserDefined.Before = Best->Conversions[0].Standard;
+    ICS.UserDefined.After = Best->FinalConversion;
+    ICS.UserDefined.ConversionFunction = Best->Function;
+    ICS.UserDefined.EllipsisConversion = false;
+    assert(ICS.UserDefined.After.ReferenceBinding &&
+           ICS.UserDefined.After.DirectBinding &&
+           "Expected a direct reference binding!");
+    return true;
+
+  case OR_Ambiguous:
+    ICS.setAmbiguous();
+    for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
+         Cand != CandidateSet.end(); ++Cand)
+      if (Cand->Viable)
+        ICS.Ambiguous.addConversion(Cand->Function);
+    return true;
+
+  case OR_No_Viable_Function:
+  case OR_Deleted:
+    // There was no suitable conversion, or we found a deleted
+    // conversion; continue with other checks.
+    return false;
+  }
+}
+
 /// \brief Compute an implicit conversion sequence for reference
 /// initialization.
 static ImplicitConversionSequence
@@ -2651,149 +2738,72 @@
   // Compute some basic properties of the types and the initializer.
   bool isRValRef = DeclType->isRValueReferenceType();
   bool DerivedToBase = false;
-  Expr::isLvalueResult InitLvalue = Init->isLvalue(S.Context);
+  Expr::Classification InitCategory = Init->Classify(S.Context);
   Sema::ReferenceCompareResult RefRelationship
     = S.CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase);
 
 
-  // C++ [over.ics.ref]p3:
-  //   Except for an implicit object parameter, for which see 13.3.1,
-  //   a standard conversion sequence cannot be formed if it requires
-  //   binding an lvalue reference to non-const to an rvalue or
-  //   binding an rvalue reference to an lvalue.
-  //
-  // FIXME: DPG doesn't trust this code. It seems far too early to
-  // abort because of a binding of an rvalue reference to an lvalue.
-  if (isRValRef && InitLvalue == Expr::LV_Valid)
-    return ICS;
-
-  // C++0x [dcl.init.ref]p16:
+  // C++0x [dcl.init.ref]p5:
   //   A reference to type "cv1 T1" is initialized by an expression
   //   of type "cv2 T2" as follows:
 
-  //     -- If the initializer expression
-  //       -- is an lvalue (but is not a bit-field), and "cv1 T1" is
-  //          reference-compatible with "cv2 T2," or
-  //
-  // Per C++ [over.ics.ref]p4, we don't check the bit-field property here.
-  if (InitLvalue == Expr::LV_Valid &&
-      RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
-    // C++ [over.ics.ref]p1:
-    //   When a parameter of reference type binds directly (8.5.3)
-    //   to an argument expression, the implicit conversion sequence
-    //   is the identity conversion, unless the argument expression
-    //   has a type that is a derived class of the parameter type,
-    //   in which case the implicit conversion sequence is a
-    //   derived-to-base Conversion (13.3.3.1).
-    ICS.setStandard();
-    ICS.Standard.First = ICK_Identity;
-    ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity;
-    ICS.Standard.Third = ICK_Identity;
-    ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
-    ICS.Standard.setToType(0, T2);
-    ICS.Standard.setToType(1, T1);
-    ICS.Standard.setToType(2, T1);
-    ICS.Standard.ReferenceBinding = true;
-    ICS.Standard.DirectBinding = true;
-    ICS.Standard.RRefBinding = false;
-    ICS.Standard.CopyConstructor = 0;
-
-    // Nothing more to do: the inaccessibility/ambiguity check for
-    // derived-to-base conversions is suppressed when we're
-    // computing the implicit conversion sequence (C++
-    // [over.best.ics]p2).
-    return ICS;
-  }
-
-  //       -- has a class type (i.e., T2 is a class type), where T1 is
-  //          not reference-related to T2, and can be implicitly
-  //          converted to an lvalue of type "cv3 T3," where "cv1 T1"
-  //          is reference-compatible with "cv3 T3" 92) (this
-  //          conversion is selected by enumerating the applicable
-  //          conversion functions (13.3.1.6) and choosing the best
-  //          one through overload resolution (13.3)),
-  if (!isRValRef && !SuppressUserConversions && T2->isRecordType() &&
-      !S.RequireCompleteType(DeclLoc, T2, 0) && 
-      RefRelationship == Sema::Ref_Incompatible) {
-    CXXRecordDecl *T2RecordDecl
-      = dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
-
-    OverloadCandidateSet CandidateSet(DeclLoc);
-    const UnresolvedSetImpl *Conversions
-      = T2RecordDecl->getVisibleConversionFunctions();
-    for (UnresolvedSetImpl::iterator I = Conversions->begin(),
-           E = Conversions->end(); I != E; ++I) {
-      NamedDecl *D = *I;
-      CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
-      if (isa<UsingShadowDecl>(D))
-        D = cast<UsingShadowDecl>(D)->getTargetDecl();
-
-      FunctionTemplateDecl *ConvTemplate
-        = dyn_cast<FunctionTemplateDecl>(D);
-      CXXConversionDecl *Conv;
-      if (ConvTemplate)
-        Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
-      else
-        Conv = cast<CXXConversionDecl>(D);
-      
-      // If the conversion function doesn't return a reference type,
-      // it can't be considered for this conversion.
-      if (Conv->getConversionType()->isLValueReferenceType() &&
-          (AllowExplicit || !Conv->isExplicit())) {
-        if (ConvTemplate)
-          S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
-                                         Init, DeclType, CandidateSet);
-        else
-          S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init,
-                                 DeclType, CandidateSet);
-      }
-    }
-
-    OverloadCandidateSet::iterator Best;
-    switch (S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
-    case OR_Success:
+  //     -- If reference is an lvalue reference and the initializer expression
+  // The next bullet point (T1 is a function) is pretty much equivalent to this
+  // one, so it's handled here.
+  if (!isRValRef || T1->isFunctionType()) {
+    //     -- is an lvalue (but is not a bit-field), and "cv1 T1" is
+    //        reference-compatible with "cv2 T2," or
+    //
+    // Per C++ [over.ics.ref]p4, we don't check the bit-field property here.
+    if (InitCategory.isLValue() &&
+        RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
       // C++ [over.ics.ref]p1:
-      //
-      //   [...] If the parameter binds directly to the result of
-      //   applying a conversion function to the argument
-      //   expression, the implicit conversion sequence is a
-      //   user-defined conversion sequence (13.3.3.1.2), with the
-      //   second standard conversion sequence either an identity
-      //   conversion or, if the conversion function returns an
-      //   entity of a type that is a derived class of the parameter
-      //   type, a derived-to-base Conversion.
-      if (!Best->FinalConversion.DirectBinding)
-        break;
+      //   When a parameter of reference type binds directly (8.5.3)
+      //   to an argument expression, the implicit conversion sequence
+      //   is the identity conversion, unless the argument expression
+      //   has a type that is a derived class of the parameter type,
+      //   in which case the implicit conversion sequence is a
+      //   derived-to-base Conversion (13.3.3.1).
+      ICS.setStandard();
+      ICS.Standard.First = ICK_Identity;
+      ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity;
+      ICS.Standard.Third = ICK_Identity;
+      ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
+      ICS.Standard.setToType(0, T2);
+      ICS.Standard.setToType(1, T1);
+      ICS.Standard.setToType(2, T1);
+      ICS.Standard.ReferenceBinding = true;
+      ICS.Standard.DirectBinding = true;
+      ICS.Standard.RRefBinding = isRValRef;
+      ICS.Standard.CopyConstructor = 0;
 
-      ICS.setUserDefined();
-      ICS.UserDefined.Before = Best->Conversions[0].Standard;
-      ICS.UserDefined.After = Best->FinalConversion;
-      ICS.UserDefined.ConversionFunction = Best->Function;
-      ICS.UserDefined.EllipsisConversion = false;
-      assert(ICS.UserDefined.After.ReferenceBinding &&
-             ICS.UserDefined.After.DirectBinding &&
-             "Expected a direct reference binding!");
+      // Nothing more to do: the inaccessibility/ambiguity check for
+      // derived-to-base conversions is suppressed when we're
+      // computing the implicit conversion sequence (C++
+      // [over.best.ics]p2).
       return ICS;
+    }
 
-    case OR_Ambiguous:
-      ICS.setAmbiguous();
-      for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
-           Cand != CandidateSet.end(); ++Cand)
-        if (Cand->Viable)
-          ICS.Ambiguous.addConversion(Cand->Function);
-      return ICS;
-
-    case OR_No_Viable_Function:
-    case OR_Deleted:
-      // There was no suitable conversion, or we found a deleted
-      // conversion; continue with other checks.
-      break;
+    //       -- has a class type (i.e., T2 is a class type), where T1 is
+    //          not reference-related to T2, and can be implicitly
+    //          converted to an lvalue of type "cv3 T3," where "cv1 T1"
+    //          is reference-compatible with "cv3 T3" 92) (this
+    //          conversion is selected by enumerating the applicable
+    //          conversion functions (13.3.1.6) and choosing the best
+    //          one through overload resolution (13.3)),
+    if (!SuppressUserConversions && T2->isRecordType() &&
+        !S.RequireCompleteType(DeclLoc, T2, 0) && 
+        RefRelationship == Sema::Ref_Incompatible) {
+      if (FindConversionToLValue(S, ICS, DeclType, DeclLoc,
+                                 Init, T2, AllowExplicit))
+        return ICS;
     }
   }
 
-  //     -- Otherwise, the reference shall be to a non-volatile const
-  //        type (i.e., cv1 shall be const), or the reference shall be an
-  //        rvalue reference and the initializer expression shall be an rvalue.
+  //     -- Otherwise, the reference shall be an lvalue reference to a
+  //        non-volatile const type (i.e., cv1 shall be const), or the reference
+  //        shall be an rvalue reference and the initializer expression shall be
+  //        an rvalue or have a function type.
   // 
   // We actually handle one oddity of C++ [over.ics.ref] at this
   // point, which is that, due to p2 (which short-circuits reference
@@ -2802,10 +2812,26 @@
   // reference to bind to an rvalue. Hence the check for the presence
   // of "const" rather than checking for "const" being the only
   // qualifier.
-  if (!isRValRef && !T1.isConstQualified())
+  // This is also the point where rvalue references and lvalue inits no longer
+  // go together.
+  if ((!isRValRef && !T1.isConstQualified()) ||
+      (isRValRef && InitCategory.isLValue()))
     return ICS;
 
-  //       -- if T2 is a class type and
+  //       -- If T1 is a function type, then
+  //          -- if T2 is the same type as T1, the reference is bound to the
+  //             initializer expression lvalue;
+  //          -- if T2 is a class type and the initializer expression can be
+  //             implicitly converted to an lvalue of type T1 [...], the
+  //             reference is bound to the function lvalue that is the result
+  //             of the conversion;
+  // This is the same as for the lvalue case above, so it was handled there.
+  //          -- otherwise, the program is ill-formed.
+  // This is the one difference to the lvalue case.
+  if (T1->isFunctionType())
+    return ICS;
+
+  //       -- Otherwise, if T2 is a class type and
   //          -- the initializer expression is an rvalue and "cv1 T1"
   //             is reference-compatible with "cv2 T2," or
   //
@@ -2824,7 +2850,7 @@
   //
   // We're only checking the first case here, which is a direct
   // binding in C++0x but not in C++03.
-  if (InitLvalue != Expr::LV_Valid && T2->isRecordType() &&
+  if (InitCategory.isRValue() && T2->isRecordType() &&
       RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
     ICS.setStandard();
     ICS.Standard.First = ICK_Identity;
