diff options
author | Nico Weber <nicolasweber@gmx.de> | 2012-06-28 23:53:12 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2012-06-28 23:53:12 +0000 |
commit | 43bb1793c523f714bca1c49d804ba7c0cb62aca2 (patch) | |
tree | 6c0b3d5896ce2002f0b2f817565d2c3d3378cc10 /lib/Sema/SemaExpr.cpp | |
parent | c99a5d820ead4e4f1f4b4a8ab61007b8da0307e6 (diff) |
Warn on self-assignment to member variables. PR13104.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159394 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index a6051d6ccc..cd3c93b720 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -7558,7 +7558,27 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { return true; } +static void CheckIdentityMemvarAssignment(Expr *LHSExpr, Expr *RHSExpr, + SourceLocation Loc, + Sema &Sema) { + // C / C++ memvars + MemberExpr *ML = dyn_cast<MemberExpr>(LHSExpr); + MemberExpr *MR = dyn_cast<MemberExpr>(RHSExpr); + if (ML && MR && ML->getMemberDecl() == MR->getMemberDecl()) { + if (isa<CXXThisExpr>(ML->getBase()) && isa<CXXThisExpr>(MR->getBase())) + Sema.Diag(Loc, diag::warn_identity_memvar_assign) << 0; + } + // Objective-C memvars + ObjCIvarRefExpr *OL = dyn_cast<ObjCIvarRefExpr>(LHSExpr); + ObjCIvarRefExpr *OR = dyn_cast<ObjCIvarRefExpr>(RHSExpr); + if (OL && OR && OL->getDecl() == OR->getDecl()) { + DeclRefExpr *RL = dyn_cast<DeclRefExpr>(OL->getBase()->IgnoreImpCasts()); + DeclRefExpr *RR = dyn_cast<DeclRefExpr>(OR->getBase()->IgnoreImpCasts()); + if (RL && RR && RL->getDecl() == RR->getDecl()) + Sema.Diag(Loc, diag::warn_identity_memvar_assign) << 1; + } +} // C99 6.5.16.1 QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, @@ -7575,6 +7595,10 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, 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()) @@ -7595,7 +7619,6 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, // 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)) { |