summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/test/cpp11-migrate/LoopConvert/naming-alias.cpp
blob: 0373d2b7473aaf0270095ad1e1303fa72f9dc76a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// 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

#include "structures.h"

const int N = 10;

Val Arr[N];
Val &func(Val &);

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;
}

void refs_and_vals() {
  // The following tests check that the transform correctly preserves the
  // reference or value qualifiers of the aliased variable. That is, if the
  // variable was declared as a value, the loop variable will be declared as a
  // value and vice versa for references.

  S s;
  const S s_const = s;

  for (S::const_iterator it = s_const.begin(); it != s_const.end(); ++it) {
    MutableVal alias = *it; { }
    alias.x = 0;
  }
  // CHECK: for (auto alias : s_const)
  // CHECK-NOT: MutableVal {{[a-z_]+}} =
  // CHECK-NEXT: { }
  // CHECK-NEXT: alias.x = 0;

  for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) {
    MutableVal alias = *it; { }
    alias.x = 0;
  }
  // CHECK: for (auto alias : s)
  // CHECK-NOT: MutableVal {{[a-z_]+}} =
  // CHECK-NEXT: { }
  // CHECK-NEXT: alias.x = 0;

  for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) {
    MutableVal &alias = *it; { }
    alias.x = 0;
  }
  // CHECK: for (auto & alias : s)
  // CHECK-NOT: MutableVal &{{[a-z_]+}} =
  // CHECK-NEXT: { }
  // CHECK-NEXT: alias.x = 0;
}
OpenPOWER on IntegriCloud