summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/test/clang-modernize/LoopConvert/naming-alias.cpp
blob: 343dd0cc650c042969d895b8840465c6ce103ac5 (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
// RUN: clang-modernize -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 sideEffect(int);

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) {
}

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