aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2012-06-28 23:53:12 +0000
committerNico Weber <nicolasweber@gmx.de>2012-06-28 23:53:12 +0000
commit43bb1793c523f714bca1c49d804ba7c0cb62aca2 (patch)
tree6c0b3d5896ce2002f0b2f817565d2c3d3378cc10 /lib/Sema/SemaExpr.cpp
parentc99a5d820ead4e4f1f4b4a8ab61007b8da0307e6 (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.cpp25
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)) {