예제 #1
0
void aliasing() {
  // If the loop container is only used for a declaration of a temporary
  // variable to hold each element, we can name the new variable for the
  // converted range-based loop as the temporary variable's name.

  // In the following case, "T" is used as a temporary variable to hold each
  // element, and thus we consider the name "T" aliased to the loop.
  // The extra blank braces are left as a placeholder for after the variable
  // declaration is deleted.
  for (int I = 0; I < N; ++I) {
    Val &T = Arr[I];
    {}
    int Y = T.X;
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & T : Arr)
  // CHECK-FIXES-NOT: Val &{{[a-z_]+}} =
  // CHECK-FIXES-NEXT: {}
  // CHECK-FIXES-NEXT: int Y = T.X;

  // The container was not only used to initialize a temporary loop variable for
  // the container's elements, so we do not alias the new loop variable.
  for (int I = 0; I < N; ++I) {
    Val &T = Arr[I];
    int Y = T.X;
    int Z = Arr[I].X + T.X;
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & I : Arr)
  // CHECK-FIXES-NEXT: Val &T = I;
  // CHECK-FIXES-NEXT: int Y = T.X;
  // CHECK-FIXES-NEXT: int Z = I.X + T.X;

  for (int I = 0; I < N; ++I) {
    Val T = Arr[I];
    int Y = T.X;
    int Z = Arr[I].X + T.X;
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & I : Arr)
  // CHECK-FIXES-NEXT: Val T = I;
  // CHECK-FIXES-NEXT: int Y = T.X;
  // CHECK-FIXES-NEXT: int Z = I.X + T.X;

  // The same for pseudo-arrays like std::vector<T> (or here dependent<Val>)
  // which provide a subscript operator[].
  for (int I = 0; I < V.size(); ++I) {
    Val &T = V[I];
    {}
    int Y = T.X;
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & T : V)
  // CHECK-FIXES-NEXT: {}
  // CHECK-FIXES-NEXT: int Y = T.X;

  // The same with a call to at()
  for (int I = 0; I < Pv->size(); ++I) {
    Val &T = Pv->at(I);
    {}
    int Y = T.X;
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & T : *Pv)
  // CHECK-FIXES-NEXT: {}
  // CHECK-FIXES-NEXT: int Y = T.X;

  for (int I = 0; I < N; ++I) {
    Val &T = func(Arr[I]);
    int Y = T.X;
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & I : Arr)
  // CHECK-FIXES-NEXT: Val &T = func(I);
  // CHECK-FIXES-NEXT: int Y = T.X;

  int IntArr[N];
  for (unsigned I = 0; I < N; ++I) {
    if (int Alias = IntArr[I]) {
      sideEffect(Alias);
    }
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int Alias : IntArr)
  // CHECK-FIXES-NEXT: if (Alias)

  for (unsigned I = 0; I < N; ++I) {
    while (int Alias = IntArr[I]) {
      sideEffect(Alias);
    }
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int Alias : IntArr)
  // CHECK-FIXES-NEXT: while (Alias)

  for (unsigned I = 0; I < N; ++I) {
    switch (int Alias = IntArr[I]) {
    default:
      sideEffect(Alias);
    }
  }
  // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int Alias : IntArr)
  // CHECK-FIXES-NEXT: switch (Alias)

  for (unsigned I = 0; I < N; ++I) {
    for (int Alias = IntArr[I]; Alias < N; ++Alias) {
      sideEffect(Alias);
    }
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int Alias : IntArr)
  // CHECK-FIXES-NEXT: for (; Alias < N; ++Alias)

  for (unsigned I = 0; I < N; ++I) {
    for (unsigned J = 0; int Alias = IntArr[I]; ++J) {
      sideEffect(Alias);
    }
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int Alias : IntArr)
  // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J)

  struct IntRef { IntRef(); IntRef(const int& i); operator int*(); };
  for (int I = 0; I < N; ++I) {
    IntRef Int(IntArr[I]);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int I : IntArr)
  // CHECK-FIXES-NEXT: IntRef Int(I);

  int *PtrArr[N];
  for (unsigned I = 0; I < N; ++I) {
    const int* const P = PtrArr[I];
    printf("%d\n", *P);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto P : PtrArr)
  // CHECK-FIXES-NEXT: printf("%d\n", *P);

  IntRef Refs[N];
  for (unsigned I = 0; I < N; ++I) {
    int *P = Refs[I];
    printf("%d\n", *P);
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & Ref : Refs)
  // CHECK-FIXES-NEXT: int *P = Ref;
  // CHECK-FIXES-NEXT: printf("%d\n", *P);

  // Ensure that removing the alias doesn't leave empty lines behind.
  for (int I = 0; I < N; ++I) {
    auto &X = IntArr[I];
    X = 0;
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (int & X : IntArr) {
  // CHECK-FIXES-NEXT: {{^    X = 0;$}}
  // CHECK-FIXES-NEXT: {{^  }$}}
}
void aliasing() {
  // If the loop container is only used for a declaration of a temporary
  // variable to hold each element, we can name the new variable for the
  // converted range-based loop as the temporary variable's name.

  // In the following case, "t" is used as a temporary variable to hold each
  // element, and thus we consider the name "t" aliased to the loop.
  // The extra blank braces are left as a placeholder for after the variable
  // declaration is deleted.
  for (int i = 0; i < N; ++i) {
    Val &t = Arr[i];
    {}
    int y = t.x;
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & t : Arr)
  // CHECK-FIXES-NOT: Val &{{[a-z_]+}} =
  // CHECK-FIXES: {}
  // CHECK-FIXES-NEXT: int y = t.x;

  // The container was not only used to initialize a temporary loop variable for
  // the container's elements, so we do not alias the new loop variable.
  for (int i = 0; i < N; ++i) {
    Val &t = Arr[i];
    int y = t.x;
    int z = Arr[i].x + t.x;
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : Arr)
  // CHECK-FIXES-NEXT: Val &t = elem;
  // CHECK-FIXES-NEXT: int y = t.x;
  // CHECK-FIXES-NEXT: int z = elem.x + t.x;

  for (int i = 0; i < N; ++i) {
    Val t = Arr[i];
    int y = t.x;
    int z = Arr[i].x + t.x;
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : Arr)
  // CHECK-FIXES-NEXT: Val t = elem;
  // CHECK-FIXES-NEXT: int y = t.x;
  // CHECK-FIXES-NEXT: int z = elem.x + t.x;

  // The same for pseudo-arrays like std::vector<T> (or here dependent<Val>)
  // which provide a subscript operator[].
  for (int i = 0; i < v.size(); ++i) {
    Val &t = v[i];
    {}
    int y = t.x;
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & t : v)
  // CHECK-FIXES: {}
  // CHECK-FIXES-NEXT: int y = t.x;

  // The same with a call to at()
  for (int i = 0; i < pv->size(); ++i) {
    Val &t = pv->at(i);
    {}
    int y = t.x;
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & t : *pv)
  // CHECK-FIXES: {}
  // CHECK-FIXES-NEXT: int y = t.x;

  for (int i = 0; i < N; ++i) {
    Val &t = func(Arr[i]);
    int y = t.x;
  }
  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : Arr)
  // CHECK-FIXES-NEXT: Val &t = func(elem);
  // CHECK-FIXES-NEXT: int y = t.x;

  int IntArr[N];
  for (unsigned i = 0; i < N; ++i) {
    if (int alias = IntArr[i]) {
      sideEffect(alias);
    }
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto alias : IntArr)
  // CHECK-FIXES-NEXT: if (alias)

  for (unsigned i = 0; i < N; ++i) {
    while (int alias = IntArr[i]) {
      sideEffect(alias);
    }
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto alias : IntArr)
  // CHECK-FIXES-NEXT: while (alias)

  for (unsigned i = 0; i < N; ++i) {
    switch (int alias = IntArr[i]) {
    default:
      sideEffect(alias);
    }
  }
  // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto alias : IntArr)
  // CHECK-FIXES-NEXT: switch (alias)

  for (unsigned i = 0; i < N; ++i) {
    for (int alias = IntArr[i]; alias < N; ++alias) {
      sideEffect(alias);
    }
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto alias : IntArr)
  // CHECK-FIXES-NEXT: for (; alias < N; ++alias)

  for (unsigned i = 0; i < N; ++i) {
    for (unsigned j = 0; int alias = IntArr[i]; ++j) {
      sideEffect(alias);
    }
  }
  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto alias : IntArr)
  // CHECK-FIXES-NEXT: for (unsigned j = 0; alias; ++j)

  struct IntRef { IntRef(const int& i); };
  for (int i = 0; i < N; ++i) {
    IntRef Int(IntArr[i]);
  }
  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
  // CHECK-FIXES: for (auto & elem : IntArr)
  // CHECK-FIXES-NEXT: IntRef Int(elem);
}
예제 #3
0
void aliasing() {
  // If the loop container is only used for a declaration of a temporary
  // variable to hold each element, we can name the new variable for the
  // converted range-based loop as the temporary variable's name.

  // In the following case, "t" is used as a temporary variable to hold each
  // element, and thus we consider the name "t" aliased to the loop.
  // The extra blank braces are left as a placeholder for after the variable
  // declaration is deleted.
  for (int i = 0; i < N; ++i) {
    Val &t = Arr[i]; { }
    int y = t.x;
  }
  // CHECK: for (auto & t : Arr)
  // CHECK-NOT: Val &{{[a-z_]+}} =
  // CHECK-NEXT: { }
  // CHECK-NEXT: int y = t.x;

  // The container was not only used to initialize a temporary loop variable for
  // the container's elements, so we do not alias the new loop variable.
  for (int i = 0; i < N; ++i) {
    Val &t = Arr[i];
    int y = t.x;
    int z = Arr[i].x + t.x;
  }
  // CHECK: for (auto & elem : Arr)
  // CHECK-NEXT: Val &t = elem;
  // CHECK-NEXT: int y = t.x;
  // CHECK-NEXT: int z = elem.x + t.x;

  for (int i = 0; i < N; ++i) {
    Val t = Arr[i];
    int y = t.x;
    int z = Arr[i].x + t.x;
  }
  // CHECK: for (auto & elem : Arr)
  // CHECK-NEXT: Val t = elem;
  // CHECK-NEXT: int y = t.x;
  // CHECK-NEXT: int z = elem.x + t.x;

  for (int i = 0; i < N; ++i) {
    Val &t = func(Arr[i]);
    int y = t.x;
  }
  // CHECK: for (auto & elem : Arr)
  // CHECK-NEXT: Val &t = func(elem);
  // CHECK-NEXT: int y = t.x;

  int IntArr[N];
  for (unsigned i = 0; i < N; ++i) {
    if (int alias = IntArr[i]) {
      sideEffect(alias);
    }
  }
  // CHECK: for (auto alias : IntArr)
  // CHECK-NEXT: if (alias) {

  for (unsigned i = 0; i < N; ++i) {
    while (int alias = IntArr[i]) {
      sideEffect(alias);
    }
  }
  // CHECK: for (auto alias : IntArr)
  // CHECK-NEXT: while (alias) {

  for (unsigned i = 0; i < N; ++i) {
    switch (int alias = IntArr[i]) {
    default:
      sideEffect(alias);
    }
  }
  // CHECK: for (auto alias : IntArr)
  // CHECK-NEXT: switch (alias) {

  for (unsigned i = 0; i < N; ++i) {
    for (int alias = IntArr[i]; alias < N; ++alias) {
      sideEffect(alias);
    }
  }
  // CHECK: for (auto alias : IntArr)
  // CHECK-NEXT: for (; alias < N; ++alias) {

  for (unsigned i = 0; i < N; ++i) {
    for (unsigned j = 0; int alias = IntArr[i]; ++j) {
      sideEffect(alias);
    }
  }
  // CHECK: for (auto alias : IntArr)
  // CHECK-NEXT: for (unsigned j = 0; alias; ++j) {
}