angelgarcia created this revision.
angelgarcia added a reviewer: alexfh.
angelgarcia added subscribers: klimek, cfe-commits.

loop-convert no longer crashes when calling a member function using a member 
pointer which is a member of another record.

http://reviews.llvm.org/D12555

Files:
  clang-tidy/modernize/LoopConvertUtils.cpp
  test/clang-tidy/modernize-loop-convert-basic.cpp

Index: test/clang-tidy/modernize-loop-convert-basic.cpp
===================================================================
--- test/clang-tidy/modernize-loop-convert-basic.cpp
+++ test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -156,6 +156,17 @@
   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & elem : mfpArr)
   // CHECK-FIXES-NEXT: (v.*elem)();
+
+  struct Foo {
+    int (Val::*f)();
+  } foo[N];
+
+  for (int i = 0; i < N; ++i)
+    int r = (v.*(foo[i].f))();
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & elem : foo)
+  // CHECK-FIXES-NEXT: int r = (v.*(elem.f))();
+
 }
 
 } // namespace Array
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===================================================================
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -370,7 +370,10 @@
 
   case Stmt::CXXMemberCallExprClass: {
     const auto *MemCall = cast<CXXMemberCallExpr>(Init);
-    if (MemCall->getMethodDecl()->getName() == "at") {
+    // This check is needed because getMethodDecl can return nullptr if the
+    // callee is a member function pointer.
+    if (MemCall->getMethodDecl() &&
+        MemCall->getMethodDecl()->getName() == "at") {
       assert(MemCall->getNumArgs() == 1);
       return isIndexInSubscriptExpr(MemCall->getArg(0), IndexVar);
     }


Index: test/clang-tidy/modernize-loop-convert-basic.cpp
===================================================================
--- test/clang-tidy/modernize-loop-convert-basic.cpp
+++ test/clang-tidy/modernize-loop-convert-basic.cpp
@@ -156,6 +156,17 @@
   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
   // CHECK-FIXES: for (auto & elem : mfpArr)
   // CHECK-FIXES-NEXT: (v.*elem)();
+
+  struct Foo {
+    int (Val::*f)();
+  } foo[N];
+
+  for (int i = 0; i < N; ++i)
+    int r = (v.*(foo[i].f))();
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & elem : foo)
+  // CHECK-FIXES-NEXT: int r = (v.*(elem.f))();
+
 }
 
 } // namespace Array
Index: clang-tidy/modernize/LoopConvertUtils.cpp
===================================================================
--- clang-tidy/modernize/LoopConvertUtils.cpp
+++ clang-tidy/modernize/LoopConvertUtils.cpp
@@ -370,7 +370,10 @@
 
   case Stmt::CXXMemberCallExprClass: {
     const auto *MemCall = cast<CXXMemberCallExpr>(Init);
-    if (MemCall->getMethodDecl()->getName() == "at") {
+    // This check is needed because getMethodDecl can return nullptr if the
+    // callee is a member function pointer.
+    if (MemCall->getMethodDecl() &&
+        MemCall->getMethodDecl()->getName() == "at") {
       assert(MemCall->getNumArgs() == 1);
       return isIndexInSubscriptExpr(MemCall->getArg(0), IndexVar);
     }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to