diff options
| author | Edwin Vane <edwin.vane@intel.com> | 2013-03-07 16:22:05 +0000 |
|---|---|---|
| committer | Edwin Vane <edwin.vane@intel.com> | 2013-03-07 16:22:05 +0000 |
| commit | 4f05d7143f5cf831e39e5ed16d33a19dc6da9dcd (patch) | |
| tree | ac54e7b59594fe75c9df0e38e5ca4c98303343a5 /clang-tools-extra/test/cpp11-migrate/LoopConvert | |
| parent | 2a760d02f718751c76db2ed3058f3624ac6ed0d4 (diff) | |
| download | bcm5719-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')
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) { - } -} |

