]> granicus.if.org Git - clang/commitdiff
add a simple check to warn people who type "=+" when they probably meant
authorChris Lattner <sabre@nondot.org>
Thu, 21 Aug 2008 18:04:13 +0000 (18:04 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 21 Aug 2008 18:04:13 +0000 (18:04 +0000)
"+=".

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55131 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticKinds.def
lib/Sema/SemaExpr.cpp
test/Sema/exprs.c

index d7eee9f1a68ee66f0110272832774e89b0cb3ab5..3e06932b2244c770f67c370e33ef33a71ea3cd75 100644 (file)
@@ -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)")
index 2bb3983acf8c128af4244c58c5681da311812742..c7db342ae4fb1421f347a62766a70e48b900c4fc 100644 (file)
@@ -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<ImplicitCastExpr>(RHSCheck))
+      RHSCheck = ICE->getSubExpr();
+    if (UnaryOperator *UO = dyn_cast<UnaryOperator>(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"))
index fc506f7a2b34f3e3fcf36c0a76c9e71acfad6c63..c98a7ed0c83748e6ec3f8ba7591ca784c9f08b4b 100644 (file)
@@ -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;
+}
+