Index: test/Sema/warn-self-assign-memvar.cpp
===================================================================
--- test/Sema/warn-self-assign-memvar.cpp	(revision 0)
+++ test/Sema/warn-self-assign-memvar.cpp	(revision 0)
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class S {
+ public:
+  int a_;
+  void s(int a) {
+    a_ = a_;  // expected-warning {{assigning member variable to itself}}
+
+    a_ += a_;  // Shouldn't warn.
+  }
+};
+
+void f0(S* s) {
+  s->a_ = s->a_;  // expected-warning {{assigning member variable to itself}}
+}
+
+void f1(S* s, S* t) {
+  // Shouldn't warn.
+  t->a_ = s->a_;
+}
+
+struct T {
+  S* s_;
+};
+
+void f2(T* t) {
+  t->s_->a_ = t->s_->a_;  // expected-warning {{assigning member variable to itself}}
+}
+
+void f3(T* t, T* t2) {
+  // Shouldn't warn.
+  t2->s_->a_ = t->s_->a_;
+}
+
+void f4(int i) {
+  // This is a common pattern to silence "parameter unused". Shouldn't warn.
+  i = i;
+
+  int j = 0;
+  j = j;  // Likewise.
+}
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td	(revision 159059)
+++ include/clang/Basic/DiagnosticGroups.td	(working copy)
@@ -166,7 +166,8 @@
 def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>;
 def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy",
                                     [CXX98CompatBindToTemporaryCopy]>;
-def SelfAssignment : DiagGroup<"self-assign">;
+def SelfAssignmentMemvar : DiagGroup<"self-assign-memvar">;
+def SelfAssignment : DiagGroup<"self-assign", [SelfAssignmentMemvar]>;
 def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
 def Sentinel : DiagGroup<"sentinel">;
 def MissingMethodReturnType : DiagGroup<"missing-method-return-type">;
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 159059)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -5258,6 +5258,10 @@
   "unspecified (use strncmp instead)">,
   InGroup<DiagGroup<"string-compare">>;
 
+def warn_identity_memvar_assign : Warning<
+  "assigning member variable to itself">,
+  InGroup<SelfAssignmentMemvar>;
+
 // Generic selections.
 def err_assoc_type_incomplete : Error<
   "type %0 in generic association incomplete">;
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 159060)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -7531,7 +7531,20 @@
   return true;
 }
 
+static void CheckIdentityMemvarAssignment(Expr *LHSExpr, Expr *RHSExpr,
+                                          SourceLocation Loc,
+                                          Sema &Sema) {
+  MemberExpr* ML = dyn_cast<MemberExpr>(LHSExpr);
+  MemberExpr* MR = dyn_cast<MemberExpr>(RHSExpr);
+  if (!ML || !MR || ML->getMemberDecl() != MR->getMemberDecl())
+    return;
 
+  llvm::FoldingSetNodeID lhsID, rhsID;
+  ML->getBase()->Profile(lhsID, Sema.Context, true);
+  MR->getBase()->Profile(rhsID, Sema.Context, true);
+  if (lhsID == rhsID)
+    Sema.Diag(Loc, diag::warn_identity_memvar_assign);
+}
 
 // C99 6.5.16.1
 QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
@@ -7548,6 +7561,10 @@
                                              CompoundType;
   AssignConvertType ConvTy;
   if (CompoundType.isNull()) {
+    Expr *RHSCheck = RHS.get();
+
+    CheckIdentityMemvarAssignment(LHSExpr, RHSCheck, Loc, *this);
+
     QualType LHSTy(LHSType);
     ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS);
     if (RHS.isInvalid())
@@ -7568,7 +7585,6 @@
     // If the RHS is a unary plus or minus, check to see if they = and + are
     // right next to each other.  If so, the user may have typo'd "x =+ 4"
     // instead of "x += 4".
-    Expr *RHSCheck = RHS.get();
     if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(RHSCheck))
       RHSCheck = ICE->getSubExpr();
     if (UnaryOperator *UO = dyn_cast<UnaryOperator>(RHSCheck)) {
