From 2c15647dce6de66f673cc64236913732d6289317 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 21 Aug 2008 18:04:13 +0000 Subject: [PATCH] add a simple check to warn people who type "=+" when they probably meant "+=". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55131 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticKinds.def | 3 +++ lib/Sema/SemaExpr.cpp | 24 ++++++++++++++++++++++-- test/Sema/exprs.c | 9 +++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index d7eee9f1a6..3e06932b22 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -1045,6 +1045,9 @@ DIAG(err_union_as_base_class, ERROR, DIAG(err_incomplete_base_class, ERROR, "base class has incomplete type") +DIAG(warn_not_compound_assign, WARNING, + "use of unary operator that may be intended as compound assignment (%0=)") + // CHECK: printf format string errors DIAG(warn_printf_not_string_constant, WARNING, "format string is not a string literal (potentially insecure)") diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 2bb3983acf..c7db342ae4 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1901,10 +1901,30 @@ inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1 } AssignConvertType ConvTy; - if (compoundType.isNull()) + if (compoundType.isNull()) { + // Simple assignment "x = y". ConvTy = CheckSingleAssignmentConstraints(lhsType, rex); - else + + // 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 = rex; + if (ImplicitCastExpr *ICE = dyn_cast(RHSCheck)) + RHSCheck = ICE->getSubExpr(); + if (UnaryOperator *UO = dyn_cast(RHSCheck)) { + if ((UO->getOpcode() == UnaryOperator::Plus || + UO->getOpcode() == UnaryOperator::Minus) && + loc.isFileID() && UO->getOperatorLoc().isFileID() && + // Only if the two operators are exactly adjacent. + loc.getFileLocWithOffset(1) == UO->getOperatorLoc()) + Diag(loc, diag::warn_not_compound_assign, + UO->getOpcode() == UnaryOperator::Plus ? "+" : "-", + SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc())); + } + } else { + // Compound assignment "x += y" ConvTy = CheckCompoundAssignmentConstraints(lhsType, rhsType); + } if (DiagnoseAssignmentResult(ConvTy, loc, lhsType, rhsType, rex, "assigning")) diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c index fc506f7a2b..c98a7ed0c8 100644 --- a/test/Sema/exprs.c +++ b/test/Sema/exprs.c @@ -15,3 +15,12 @@ void test3() { (__extension__ x) = 10; } +// rdar://6162726 +void test4() { + static int var; + var =+ 5; // expected-warning {{use of unary operator that may be intended as compound assignment (+=)}} + var =- 5; // expected-warning {{use of unary operator that may be intended as compound assignment (-=)}} + var = +5; + var = -5; +} + -- 2.40.0