Assignment and Inc/Dec operators wouldn't register as a mutation when Implicit Paren...
authorTridacnid <tridacnid@gmail.com>
Tue, 9 Jun 2020 18:43:48 +0000 (19:43 +0100)
committerNathan James <n.james93@hotmail.co.uk>
Tue, 9 Jun 2020 18:45:57 +0000 (19:45 +0100)
Add ignoringParenImpCasts to assignment and inc/dec mutation checks in ExprMutationAnalyzer to fix clang-tidy bug PR45490.
https://bugs.llvm.org/show_bug.cgi?id=45490

Reviewed By: njames93, aaron.ballman, gribozavr2

Differential Revision: https://reviews.llvm.org/D79912

clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
clang/lib/Analysis/ExprMutationAnalyzer.cpp
clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp

index 427b5f0..8bd4df7 100644 (file)
@@ -70,11 +70,25 @@ void simple_not_infinite1() {
     i++;
   }
 
+  while ((Limit)--) {
+    // Not an error since 'Limit' is updated.
+    i++;
+  }
+
+  while ((Limit) -= 1) {
+    // Not an error since 'Limit' is updated.
+  }
+
   while (int k = Limit) {
     // Not an error since 'Limit' is updated.
     Limit--;
   }
 
+  while (int k = Limit) {
+    // Not an error since 'Limit' is updated
+    (Limit)--;
+  }
+
   while (int k = Limit--) {
     // Not an error since 'Limit' is updated.
     i++;
@@ -86,6 +100,15 @@ void simple_not_infinite1() {
 
   for (i = 0; i < Limit; Limit--) {
   }
+
+  for (i = 0; i < Limit; (Limit) = Limit - 1) {
+  }
+
+  for (i = 0; i < Limit; (Limit) -= 1) {
+  }
+
+  for (i = 0; i < Limit; --(Limit)) {
+  }
 }
 
 void simple_not_infinite2() {
index cb5cabf..2f80285 100644 (file)
@@ -201,14 +201,15 @@ const Stmt *ExprMutationAnalyzer::findDeclPointeeMutation(
 
 const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
   // LHS of any assignment operators.
-  const auto AsAssignmentLhs =
-      binaryOperator(isAssignmentOperator(),
-                     hasLHS(maybeEvalCommaExpr(equalsNode(Exp))));
+  const auto AsAssignmentLhs = binaryOperator(
+      isAssignmentOperator(),
+      hasLHS(maybeEvalCommaExpr(ignoringParenImpCasts(equalsNode(Exp)))));
 
   // Operand of increment/decrement operators.
   const auto AsIncDecOperand =
       unaryOperator(anyOf(hasOperatorName("++"), hasOperatorName("--")),
-                    hasUnaryOperand(maybeEvalCommaExpr(equalsNode(Exp))));
+                    hasUnaryOperand(maybeEvalCommaExpr(
+                        ignoringParenImpCasts(equalsNode(Exp)))));
 
   // Invoking non-const member function.
   // A member function is assumed to be non-const when it is unresolved.
index 9b0a3db..9d26eeb 100644 (file)
@@ -112,11 +112,21 @@ TEST(ExprMutationAnalyzerTest, Trivial) {
 class AssignmentTest : public ::testing::TestWithParam<std::string> {};
 
 TEST_P(AssignmentTest, AssignmentModifies) {
-  const std::string ModExpr = "x " + GetParam() + " 10";
-  const auto AST = buildASTFromCode("void f() { int x; " + ModExpr + "; }");
-  const auto Results =
-      match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
-  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre(ModExpr));
+  {
+    const std::string ModExpr = "x " + GetParam() + " 10";
+    const auto AST = buildASTFromCode("void f() { int x; " + ModExpr + "; }");
+    const auto Results =
+        match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+    EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre(ModExpr));
+  }
+
+  {
+    const std::string ModExpr = "(x) " + GetParam() + " 10";
+    const auto AST = buildASTFromCode("void f() { int x; " + ModExpr + "; }");
+    const auto Results =
+        match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+    EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre(ModExpr));
+  }
 }
 
 INSTANTIATE_TEST_CASE_P(AllAssignmentOperators, AssignmentTest,
@@ -134,7 +144,8 @@ TEST_P(IncDecTest, IncDecModifies) {
 }
 
 INSTANTIATE_TEST_CASE_P(AllIncDecOperators, IncDecTest,
-                        Values("++x", "--x", "x++", "x--"), );
+                        Values("++x", "--x", "x++", "x--", "++(x)", "--(x)",
+                               "(x)++", "(x)--"), );
 
 TEST(ExprMutationAnalyzerTest, NonConstMemberFunc) {
   const auto AST = buildASTFromCode(