summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/test/cpp11-migrate/LoopConvert
diff options
context:
space:
mode:
authorEdwin Vane <edwin.vane@intel.com>2013-03-07 16:22:05 +0000
committerEdwin Vane <edwin.vane@intel.com>2013-03-07 16:22:05 +0000
commit4f05d7143f5cf831e39e5ed16d33a19dc6da9dcd (patch)
treeac54e7b59594fe75c9df0e38e5ca4c98303343a5 /clang-tools-extra/test/cpp11-migrate/LoopConvert
parent2a760d02f718751c76db2ed3058f3624ac6ed0d4 (diff)
downloadbcm5719-llvm-4f05d7143f5cf831e39e5ed16d33a19dc6da9dcd.tar.gz
bcm5719-llvm-4f05d7143f5cf831e39e5ed16d33a19dc6da9dcd.zip
Have LoopConvert use 'auto &&' where necessary
For iterators where the dereference operator returns by value, LoopConvert should use 'auto &&' in the range-based for loop expression. If the dereference operator returns an rvalue reference, this is deemed too strange and the for loop is not converted. Moved test case from iterator_failing.cpp to iterator.cpp and added extra tests. Fixes PR15437. Reviewer: gribozavr llvm-svn: 176631
Diffstat (limited to 'clang-tools-extra/test/cpp11-migrate/LoopConvert')
-rw-r--r--clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/structures.h23
-rw-r--r--clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator.cpp33
-rw-r--r--clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator_failing.cpp14
3 files changed, 55 insertions, 15 deletions
diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/structures.h b/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/structures.h
index 3379b05ac1e..e37f2b54794 100644
--- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/structures.h
+++ b/clang-tools-extra/test/cpp11-migrate/LoopConvert/Inputs/structures.h
@@ -150,4 +150,27 @@ struct PtrSet {
iterator end() const;
};
+template <typename T>
+struct TypedefDerefContainer {
+ struct iterator {
+ typedef T &deref_type;
+ bool operator!=(const iterator &other) const;
+ deref_type operator*();
+ iterator &operator++();
+ };
+ iterator begin() const;
+ iterator end() const;
+};
+
+template <typename T>
+struct RValueDerefContainer {
+ struct iterator {
+ typedef T &&deref_type;
+ bool operator!=(const iterator &other) const;
+ deref_type operator*();
+ iterator &operator++();
+ };
+ iterator begin() const;
+ iterator end() const;
+};
#endif // STRUCTURES_H
diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator.cpp
index a59a90fbfa1..fc36e07fe8b 100644
--- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator.cpp
+++ b/clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator.cpp
@@ -1,5 +1,5 @@
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
-// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs
+// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs -std=c++11
// RUN: FileCheck -input-file=%t.cpp %s
// RUN: cpp11-migrate -loop-convert %t.cpp -risk=risky -- -I %S/Inputs
// RUN: FileCheck -check-prefix=RISKY -input-file=%t.cpp %s
@@ -101,6 +101,37 @@ void f() {
}
// CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : intmap)
// CHECK-NEXT: printf("intmap[%d] = %d", [[VAR]].first, [[VAR]].second);
+
+ // PtrSet's iterator dereferences by value so auto & can't be used.
+ {
+ PtrSet<int*> int_ptrs;
+ for (PtrSet<int*>::iterator I = int_ptrs.begin(),
+ E = int_ptrs.end(); I != E; ++I) {
+ // CHECK: for (auto && int_ptr : int_ptrs) {
+ }
+ }
+
+ // This container uses an iterator where the derefence type is a typedef of
+ // a reference type. Make sure non-const auto & is still used. A failure here
+ // means canonical types aren't being tested.
+ {
+ TypedefDerefContainer<int> int_ptrs;
+ for (TypedefDerefContainer<int>::iterator I = int_ptrs.begin(),
+ E = int_ptrs.end(); I != E; ++I) {
+ // CHECK: for (auto & int_ptr : int_ptrs) {
+ }
+ }
+
+ {
+ // Iterators returning an rvalue reference should disqualify the loop from
+ // transformation.
+ RValueDerefContainer<int> container;
+ for (RValueDerefContainer<int>::iterator I = container.begin(),
+ E = container.end(); I != E; ++I) {
+ // CHECK: for (RValueDerefContainer<int>::iterator I = container.begin(),
+ // CHECK-NEXT: E = container.end(); I != E; ++I) {
+ }
+ }
}
// Tests to ensure that an implicit 'this' is picked up as the container.
diff --git a/clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator_failing.cpp b/clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator_failing.cpp
deleted file mode 100644
index 5684497f745..00000000000
--- a/clang-tools-extra/test/cpp11-migrate/LoopConvert/iterator_failing.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
-// RUN: cpp11-migrate -loop-convert %t.cpp -- -I %S/Inputs
-// RUN: FileCheck -input-file=%t.cpp %s
-// XFAIL: *
-#include "structures.h"
-
-void f() {
- // See PR15437 for details.
- PtrSet<int*> int_ptrs;
- for (PtrSet<int*>::iterator I = int_ptrs.begin(),
- E = int_ptrs.end(); I != E; ++I) {
- // CHECK: for (const auto & int_ptr : int_ptrs) {
- }
-}
OpenPOWER on IntegriCloud