[clang-tools-extra] r251940 - Improve more the const-detection in modernize-loop-convert.

Angel Garcia Gomez via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 3 08:31:37 PST 2015


Author: angelgarcia
Date: Tue Nov  3 10:31:36 2015
New Revision: 251940

URL: http://llvm.org/viewvc/llvm-project?rev=251940&view=rev
Log:
Improve more the const-detection in modernize-loop-convert.

Summary: The previous change was focused in detecting when a non-const object was used in a constant way. Looks like I forgot the most important and trivial case: when the object is already constant. Failing to detect this cases results in compile errors, due to trying to bind a constant object to a non-const reference in the range-for statement. This change should fix that.

Reviewers: klimek

Subscribers: alexfh, cfe-commits

Differential Revision: http://reviews.llvm.org/D14282

Modified:
    clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
    clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp

Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=251940&r1=251939&r2=251940&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Tue Nov  3 10:31:36 2015
@@ -372,6 +372,8 @@ static bool isDirectMemberExpr(const Exp
 /// containter that we are iterating over, returns false when it can be
 /// guaranteed this element cannot be modified as a result of this usage.
 static bool canBeModified(ASTContext *Context, const Expr *E) {
+  if (E->getType().isConstQualified())
+    return false;
   auto Parents = Context->getParents(*E);
   if (Parents.size() != 1)
     return true;

Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp?rev=251940&r1=251939&r2=251940&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp Tue Nov  3 10:31:36 2015
@@ -271,28 +271,91 @@ void takingReferences() {
   // Aliases.
   for (int I = 0; I < N; ++I) {
     const Str &J = Array[I];
-    (void) J;
+    (void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (auto J : Array)
   for (int I = 0; I < N; ++I) {
     Str &J = Array[I];
-    (void) J;
+    (void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (auto & J : Array)
 
   for (int I = 0; I < N; ++I) {
     const int &J = Ints[I];
-    (void) J;
+    (void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (int J : Ints)
 
   for (int I = 0; I < N; ++I) {
     int &J = Ints[I];
-    (void) J;
+    (void)J;
   }
   // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
   // CHECK-FIXES: for (int & J : Ints)
 }
+
+template <class T>
+struct vector {
+  unsigned size() const;
+  const T &operator[](int) const;
+  T &operator[](int);
+  T *begin();
+  T *end();
+  const T *begin() const;
+  const T *end() const;
+};
+
+// If the elements are already constant, we won't do any ImplicitCast to const.
+void testContainerOfConstElements() {
+  const int Ints[N]{};
+  for (int I = 0; I < N; ++I) {
+    OtherInt -= Ints[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+
+  vector<const Str> Strs;
+  for (int I = 0; I < Strs.size(); ++I) {
+    Strs[I].constMember(0);
+    constRefArg(Strs[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto Str : Strs)
+}
+
+// When we are inside a const-qualified member functions, all the data members
+// are implicitly set as const. As before, there won't be any ImplicitCast to
+// const in their usages.
+class TestInsideConstFunction {
+  const static int N = 10;
+  int Ints[N];
+  Str Array[N];
+  vector<int> V;
+
+  void foo() const {
+    for (int I = 0; I < N; ++I) {
+      if (Ints[I])
+        copyArg(Ints[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+    // CHECK-FIXES: for (int Elem : Ints)
+
+    for (int I = 0; I < N; ++I) {
+      Array[I].constMember(0);
+      constRefArg(Array[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+    // CHECK-FIXES: for (auto Elem : Array)
+
+    for (int I = 0; I < V.size(); ++I) {
+      if (V[I])
+        copyArg(V[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+    // CHECK-FIXES: for (int Elem : V)
+
+  }
+};




More information about the cfe-commits mailing list