void f() {
  /// begin()/end() - based for loops here:
  T t;
  for (T::iterator it = t.begin(); it != t.end(); ++it) {
    printf("I found %d\n", *it);
  }
  // CHECK: for ({{[a-zA-Z_ ]+&? ?}}[[VAR:[a-z_]+]] : t)
  // CHECK-NEXT: printf("I found %d\n", [[VAR]]);

  T *pt;
  for (T::iterator it = pt->begin(); it != pt->end(); ++it) {
    printf("I found %d\n", *it);
  }
  // CHECK: for ({{[a-zA-Z_ ]+&? ?}}[[VAR:[a-z_]+]] : *pt)
  // CHECK-NEXT: printf("I found %d\n", [[VAR]]);

  S s;
  for (S::const_iterator it = s.begin(); it != s.end(); ++it) {
    printf("s has value %d\n", (*it).x);
  }
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : s)
  // CHECK-NEXT: printf("s has value %d\n", ([[VAR]]).x);

  S *ps;
  for (S::const_iterator it = ps->begin(); it != ps->end(); ++it) {
    printf("s has value %d\n", (*it).x);
  }
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : *ps)
  // CHECK-NEXT: printf("s has value %d\n", ([[VAR]]).x);

  for (S::const_iterator it = s.begin(); it != s.end(); ++it) {
    printf("s has value %d\n", it->x);
  }
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : s)
  // CHECK-NEXT: printf("s has value %d\n", [[VAR]].x);

  for (S::iterator it = s.begin(); it != s.end(); ++it) {
    it->x = 3;
  }
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : s)
  // CHECK-NEXT: [[VAR]].x = 3;

  for (S::iterator it = s.begin(); it != s.end(); ++it) {
    (*it).x = 3;
  }
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : s)
  // CHECK-NEXT: ([[VAR]]).x = 3;

  for (S::iterator it = s.begin(); it != s.end(); ++it) {
    it->nonConstFun(4, 5);
  }
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : s)
  // CHECK-NEXT: [[VAR]].nonConstFun(4, 5);

  U u;
  for (U::iterator it = u.begin(); it != u.end(); ++it) {
    printf("s has value %d\n", it->x);
  }
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : u)
  // CHECK-NEXT: printf("s has value %d\n", [[VAR]].x);

  for (U::iterator it = u.begin(); it != u.end(); ++it) {
    printf("s has value %d\n", (*it).x);
  }
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : u)
  // CHECK-NEXT: printf("s has value %d\n", ([[VAR]]).x);

  U::iterator A;
  for (U::iterator i = u.begin(); i != u.end(); ++i)
    int k = A->x + i->x;
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : u)
  // CHECK-NEXT: int k = A->x + [[VAR]].x;

  dependent<int> v;
  for (dependent<int>::const_iterator it = v.begin();
       it != v.end(); ++it) {
    printf("Fibonacci number is %d\n", *it);
  }
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : v)
  // CHECK-NEXT: printf("Fibonacci number is %d\n", [[VAR]]);

  for (dependent<int>::const_iterator it(v.begin());
       it != v.end(); ++it) {
    printf("Fibonacci number is %d\n", *it);
  }
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : v)
  // CHECK-NEXT: printf("Fibonacci number is %d\n", [[VAR]]);

  doublyDependent<int,int> intmap;
  for (doublyDependent<int,int>::iterator it = intmap.begin();
       it != intmap.end(); ++it) {
    printf("intmap[%d] = %d", it->first, it->second);
  }
  // CHECK: for ({{[a-zA-Z_ ]*&? ?}}[[VAR:[a-z_]+]] : intmap)
  // CHECK-NEXT: printf("intmap[%d] = %d", [[VAR]].first, [[VAR]].second);
}
void f() {
  /// begin()/end() - based for loops here:
  T t;
  for (T::iterator it = t.begin(); it != t.end(); ++it) {
    printf("I found %d\n", *it);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : t)
  // CHECK-FIXES-NEXT: printf("I found %d\n", elem);

  T *pt;
  for (T::iterator it = pt->begin(); it != pt->end(); ++it) {
    printf("I found %d\n", *it);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : *pt)
  // CHECK-FIXES-NEXT: printf("I found %d\n", elem);

  S s;
  for (S::iterator it = s.begin(); it != s.end(); ++it) {
    printf("s has value %d\n", (*it).x);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : s)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x);

  S *ps;
  for (S::iterator it = ps->begin(); it != ps->end(); ++it) {
    printf("s has value %d\n", (*it).x);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & p : *ps)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", (p).x);

  for (S::iterator it = s.begin(); it != s.end(); ++it) {
    printf("s has value %d\n", it->x);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : s)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x);

  for (S::iterator it = s.begin(); it != s.end(); ++it) {
    it->x = 3;
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : s)
  // CHECK-FIXES-NEXT: elem.x = 3;

  for (S::iterator it = s.begin(); it != s.end(); ++it) {
    (*it).x = 3;
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : s)
  // CHECK-FIXES-NEXT: (elem).x = 3;

  for (S::iterator it = s.begin(); it != s.end(); ++it) {
    it->nonConstFun(4, 5);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : s)
  // CHECK-FIXES-NEXT: elem.nonConstFun(4, 5);

  U u;
  for (U::iterator it = u.begin(); it != u.end(); ++it) {
    printf("s has value %d\n", it->x);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : u)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x);

  for (U::iterator it = u.begin(); it != u.end(); ++it) {
    printf("s has value %d\n", (*it).x);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : u)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x);

  U::iterator A;
  for (U::iterator i = u.begin(); i != u.end(); ++i)
    int k = A->x + i->x;
  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : u)
  // CHECK-FIXES-NEXT: int k = A->x + elem.x;

  dependent<int> v;
  for (dependent<int>::iterator it = v.begin();
       it != v.end(); ++it) {
    printf("Fibonacci number is %d\n", *it);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : v)
  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", elem);

  for (dependent<int>::iterator it(v.begin());
       it != v.end(); ++it) {
    printf("Fibonacci number is %d\n", *it);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : v)
  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", elem);

  doublyDependent<int, int> intmap;
  for (doublyDependent<int, int>::iterator it = intmap.begin();
       it != intmap.end(); ++it) {
    printf("intmap[%d] = %d", it->first, it->second);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : intmap)
  // CHECK-FIXES-NEXT: printf("intmap[%d] = %d", elem.first, elem.second);
}
void f() {
  /// begin()/end() - based for loops here:
  T Tt;
  for (T::iterator It = Tt.begin(); It != Tt.end(); ++It) {
    printf("I found %d\n", *It);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int & It : Tt)
  // CHECK-FIXES-NEXT: printf("I found %d\n", It);

  T *Pt;
  for (T::iterator It = Pt->begin(); It != Pt->end(); ++It) {
    printf("I found %d\n", *It);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int & It : *Pt)
  // CHECK-FIXES-NEXT: printf("I found %d\n", It);

  S Ss;
  for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
    printf("s has value %d\n", (*It).X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & It : Ss)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);

  S *Ps;
  for (S::iterator It = Ps->begin(); It != Ps->end(); ++It) {
    printf("s has value %d\n", (*It).X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & P : *Ps)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);

  for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
    printf("s has value %d\n", It->X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & It : Ss)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);

  for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
    It->X = 3;
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & It : Ss)
  // CHECK-FIXES-NEXT: It.X = 3;

  for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
    (*It).X = 3;
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & It : Ss)
  // CHECK-FIXES-NEXT: It.X = 3;

  for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
    It->nonConstFun(4, 5);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & It : Ss)
  // CHECK-FIXES-NEXT: It.nonConstFun(4, 5);

  U Uu;
  for (U::iterator It = Uu.begin(); It != Uu.end(); ++It) {
    printf("s has value %d\n", It->X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & It : Uu)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);

  for (U::iterator It = Uu.begin(); It != Uu.end(); ++It) {
    printf("s has value %d\n", (*It).X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & It : Uu)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);

  U::iterator A;
  for (U::iterator I = Uu.begin(); I != Uu.end(); ++I)
    int K = A->X + I->X;
  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & I : Uu)
  // CHECK-FIXES-NEXT: int K = A->X + I.X;

  dependent<int> V;
  for (dependent<int>::iterator It = V.begin();
       It != V.end(); ++It) {
    printf("Fibonacci number is %d\n", *It);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int & It : V)
  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);

  for (dependent<int>::iterator It(V.begin());
       It != V.end(); ++It) {
    printf("Fibonacci number is %d\n", *It);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int & It : V)
  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);

  doublyDependent<int, int> intmap;
  for (doublyDependent<int, int>::iterator It = intmap.begin();
       It != intmap.end(); ++It) {
    printf("intmap[%d] = %d", It->first, It->second);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & It : intmap)
  // CHECK-FIXES-NEXT: printf("intmap[%d] = %d", It.first, It.second);
}
void f() {
  /// begin()/end() - based for loops here:
  T Tt;
  for (T::iterator It = Tt.begin(), E = Tt.end(); It != E; ++It) {
    printf("I found %d\n", *It);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int & Elem : Tt)
  // CHECK-FIXES-NEXT: printf("I found %d\n", Elem);

  T *Pt;
  for (T::iterator It = Pt->begin(), E = Pt->end(); It != E; ++It) {
    printf("I found %d\n", *It);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int & Elem : *Pt)
  // CHECK-FIXES-NEXT: printf("I found %d\n", Elem);

  S Ss;
  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
    printf("s has value %d\n", (*It).X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Elem : Ss)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", Elem.X);

  S *Ps;
  for (S::iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) {
    printf("s has value %d\n", (*It).X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & P : *Ps)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);

  for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) {
    printf("s has value %d\n", (*It).X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto Elem : Ss)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", Elem.X);

  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
    printf("s has value %d\n", It->X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Elem : Ss)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", Elem.X);

  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
    It->X = 3;
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Elem : Ss)
  // CHECK-FIXES-NEXT: Elem.X = 3;

  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
    (*It).X = 3;
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Elem : Ss)
  // CHECK-FIXES-NEXT: Elem.X = 3;

  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
    It->nonConstFun(4, 5);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Elem : Ss)
  // CHECK-FIXES-NEXT: Elem.nonConstFun(4, 5);

  U Uu;
  for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {
    printf("s has value %d\n", It->X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Elem : Uu)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", Elem.X);

  for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {
    printf("s has value %d\n", (*It).X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Elem : Uu)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", Elem.X);

  U::iterator A;
  for (U::iterator I = Uu.begin(), E = Uu.end(); I != E; ++I)
    int K = A->X + I->X;
  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Elem : Uu)
  // CHECK-FIXES-NEXT: int K = A->X + Elem.X;

  dependent<int> V;
  for (dependent<int>::iterator It = V.begin(), E = V.end();
       It != E; ++It) {
    printf("Fibonacci number is %d\n", *It);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int & Elem : V)
  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);

  for (dependent<int>::iterator It(V.begin()), E = V.end();
       It != E; ++It) {
    printf("Fibonacci number is %d\n", *It);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int & Elem : V)
  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem);

  doublyDependent<int, int> Intmap;
  for (doublyDependent<int, int>::iterator It = Intmap.begin(), E = Intmap.end();
       It != E; ++It) {
    printf("Intmap[%d] = %d", It->first, It->second);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Elem : Intmap)
  // CHECK-FIXES: printf("Intmap[%d] = %d", Elem.first, Elem.second);

  // PtrSet's iterator dereferences by value so auto & can't be used.
  {
    PtrSet<int *> Val_int_ptrs;
    for (PtrSet<int *>::iterator I = Val_int_ptrs.begin(),
                                 E = Val_int_ptrs.end();
         I != E; ++I) {
      (void) *I;
    }
    // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
    // CHECK-FIXES: for (auto Val_int_ptr : Val_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) {
      (void) *I;
    }
    // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
    // CHECK-FIXES: for (int & 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) {
      (void) *I;
    }
  }

  dependent<Val *> Dpp;
  for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) {
    printf("%d\n", (**I).X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Elem : Dpp)
  // CHECK-FIXES-NEXT: printf("%d\n", (*Elem).X);

  for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) {
    printf("%d\n", (*I)->X);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Elem : Dpp)
  // CHECK-FIXES-NEXT: printf("%d\n", Elem->X);
}
void f() {
  /// begin()/end() - based for loops here:
  T t;
  for (T::iterator it = t.begin(), e = t.end(); it != e; ++it) {
    printf("I found %d\n", *it);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : t)
  // CHECK-FIXES-NEXT: printf("I found %d\n", elem);

  T *pt;
  for (T::iterator it = pt->begin(), e = pt->end(); it != e; ++it) {
    printf("I found %d\n", *it);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : *pt)
  // CHECK-FIXES-NEXT: printf("I found %d\n", elem);

  S s;
  for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) {
    printf("s has value %d\n", (*it).x);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : s)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x);

  S *ps;
  for (S::iterator it = ps->begin(), e = ps->end(); it != e; ++it) {
    printf("s has value %d\n", (*it).x);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & p : *ps)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", (p).x);

  for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) {
    printf("s has value %d\n", it->x);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : s)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x);

  for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) {
    it->x = 3;
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : s)
  // CHECK-FIXES-NEXT: elem.x = 3;

  for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) {
    (*it).x = 3;
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : s)
  // CHECK-FIXES-NEXT: (elem).x = 3;

  for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) {
    it->nonConstFun(4, 5);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : s)
  // CHECK-FIXES-NEXT: elem.nonConstFun(4, 5);

  U u;
  for (U::iterator it = u.begin(), e = u.end(); it != e; ++it) {
    printf("s has value %d\n", it->x);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : u)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x);

  for (U::iterator it = u.begin(), e = u.end(); it != e; ++it) {
    printf("s has value %d\n", (*it).x);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : u)
  // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x);

  U::iterator A;
  for (U::iterator i = u.begin(), e = u.end(); i != e; ++i)
    int k = A->x + i->x;
  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : u)
  // CHECK-FIXES-NEXT: int k = A->x + elem.x;

  dependent<int> v;
  for (dependent<int>::iterator it = v.begin(), e = v.end();
       it != e; ++it) {
    printf("Fibonacci number is %d\n", *it);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : v) {
  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", elem);

  for (dependent<int>::iterator it(v.begin()), e = v.end();
       it != e; ++it) {
    printf("Fibonacci number is %d\n", *it);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : v) {
  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", elem);

  doublyDependent<int, int> intmap;
  for (doublyDependent<int, int>::iterator it = intmap.begin(), e = intmap.end();
       it != e; ++it) {
    printf("intmap[%d] = %d", it->first, it->second);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : intmap)
  // CHECK-FIXES: printf("intmap[%d] = %d", elem.first, elem.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-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop instead
    // CHECK-FIXES: 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-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop instead
    // CHECK-FIXES: 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-FIXES: for (RValueDerefContainer<int>::iterator I = container.begin(),
    // CHECK-FIXES-NEXT: E = container.end();
    // CHECK-FIXES-NEXT: I != E; ++I) {
  }
}