Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 148604)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -1608,7 +1608,8 @@
                                SourceLocation RParenLoc);
 
   ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base,
-                                      SourceLocation OpLoc);
+                                      SourceLocation OpLoc, 
+                                      bool &retryAsPeriod);
 
   /// CheckCallReturnType - Checks that a call expression's return type is
   /// complete. Returns true on failure. The location passed in is the location
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp	(revision 148604)
+++ lib/Sema/SemaExprCXX.cpp	(working copy)
@@ -4237,6 +4237,8 @@
 Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc,
                                    tok::TokenKind OpKind, ParsedType &ObjectType,
                                    bool &MayBePseudoDestructor) {
+  Expr *OriginalBase = Base;
+
   // Since this might be a postfix expression, get rid of ParenListExprs.
   ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
   if (Result.isInvalid()) return ExprError();
@@ -4271,7 +4273,11 @@
     CTypes.insert(Context.getCanonicalType(BaseType));
 
     while (BaseType->isRecordType()) {
-      Result = BuildOverloadedArrowExpr(S, Base, OpLoc);
+      bool retryAsPeriod = false;
+      Result = BuildOverloadedArrowExpr(S, Base, OpLoc, retryAsPeriod);
+      if (retryAsPeriod)
+        return ActOnStartCXXMemberReference(S, OriginalBase, OpLoc, 
+                tok::period, ObjectType, MayBePseudoDestructor);
       if (Result.isInvalid())
         return ExprError();
       Base = Result.get();
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp	(revision 148604)
+++ lib/Sema/SemaOverload.cpp	(working copy)
@@ -10509,7 +10509,8 @@
 ///  (if one exists), where @c Base is an expression of class type and
 /// @c Member is the name of the member we're trying to find.
 ExprResult
-Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
+Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, 
+                                bool &retryAsPeriod) {
   assert(Base->getType()->isRecordType() &&
          "left-hand side must have class type");
 
@@ -10554,12 +10555,15 @@
     break;
 
   case OR_No_Viable_Function:
-    if (CandidateSet.empty())
-      Diag(OpLoc, diag::err_typecheck_member_reference_arrow)
-        << Base->getType() << Base->getSourceRange();
-    else
+    if (CandidateSet.empty()) {
+//      Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+//        << Base->getType() << 1 /*Is Arrow*/ << Base->getSourceRange()
+//        << FixItHint::CreateReplacement(OpLoc, ".");
+        retryAsPeriod = true;
+    } else {
       Diag(OpLoc, diag::err_ovl_no_viable_oper)
         << "operator->" << Base->getSourceRange();
+    }
     CandidateSet.NoteCandidates(*this, OCD_AllCandidates, &Base, 1);
     return ExprError();
 
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h	(revision 148604)
+++ lib/Sema/TreeTransform.h	(working copy)
@@ -8541,7 +8541,8 @@
                                                        Second, OpLoc);
   } else if (Op == OO_Arrow) {
     // -> is never a builtin operation.
-    return SemaRef.BuildOverloadedArrowExpr(0, First, OpLoc);
+    bool retryAsPeriod; // We ignore this since we can't recover
+    return SemaRef.BuildOverloadedArrowExpr(0, First, OpLoc, retryAsPeriod);
   } else if (Second == 0 || isPostIncDec) {
     if (!First->getType()->isOverloadableType()) {
       // The argument is not of overloadable type, so try to create a
Index: test/FixIt/fixit-member-reference.cpp
===================================================================
--- test/FixIt/fixit-member-reference.cpp	(revision 0)
+++ test/FixIt/fixit-member-reference.cpp	(working copy)
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: not %clang_cc1 -fsyntax-only -fixit -x c++ %t
+// RUN: %clang_cc1 -fsyntax-only -pedantic -x c++ %t
+
+struct S {
+  int member;
+};
+
+void foo() {
+  struct S s;
+  struct S *ps;
+
+  s->member = 12; // expected-error{{member reference type 'struct S' is not a pointer; maybe you meant to use '.'?}}
+  ps.member = 12; // expected-error{{member reference type 'struct S *' is a pointer; maybe you meant to use '->'?}}
+}
