summaryrefslogtreecommitdiffstats
path: root/test/CodeGen/volatile-1.c
blob: ac3b4c2e97b2eca33a1281ca13ea055bcfdefebc (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
140
141
142
143
// RUN: clang-cc -Wno-unused-value -emit-llvm < %s -o %t &&
// RUN: grep volatile %t | count 145 &&
// RUN: grep memcpy %t | count 4

volatile int i, j, k;
volatile int ar[5];
volatile char c;
volatile _Complex int ci;
volatile struct S {
#ifdef __cplusplus
  void operator =(volatile struct S&o) volatile;
#endif
  int i;
} a, b;

//void operator =(volatile struct S&o1, volatile struct S&o2) volatile;
#include <stdio.h>

int main() {
  // A use.
  i;
  // A use of the real part
  (float)(ci);
  // A use.
  (void)ci;
  // A use.
  (void)a;
  // Not a use.
  (void)(ci=ci);
  // Not a use.
  (void)(i=j);
  ci+=ci;
  (ci += ci) + ci;
  asm("nop");
  (i += j) + k;
  asm("nop");
  // A use
  (i += j) + 1;
  asm("nop");
  ci+ci;
  // A use.
  __real i;
  // A use.
  +ci;
  asm("nop");
  // Not a use.
  (void)(i=i);
  (float)(i=i);
  // A use.
  (void)i;
  i=i;
  i=i=i;
#ifndef __cplusplus
  // Not a use.
  (void)__builtin_choose_expr(0, i=i, j=j);
#endif
  // A use.
  k ? (i=i) : (j=j);
  (void)(i,(i=i));
  i=i,i;
  (i=j,k=j);
  (i=j,k);
  (i,j);
  i=c=k;
  i+=k;
  // A use of both.
  ci;
#ifndef __cplusplus
  // A use of _real.
  (int)ci;
  // A use of both.
  (_Bool)ci;
#endif
  ci=ci;
  ci=ci=ci;
  __imag ci = __imag ci = __imag ci;
  // Not a use.
  __real (i = j);
  // Not a use.
  __imag i;
  
  // ============================================================
  // FIXME: Test cases we get wrong.

  // A use.  We load all of a into a copy of a, then load i.  gcc forgets to do
  // the assignment.
  // (a = a).i;

  // ============================================================
  // Test cases where we intentionally differ from gcc, due to suspected bugs in
  // gcc.

  // Not a use.  gcc forgets to do the assignment.
  ((a=a),a);

  // Not a use.  gcc gets this wrong, it doesn't emit the copy!  
  // (void)(a=a);

  // Not a use.  gcc got this wrong in 4.2 and omitted the side effects
  // entirely, but it is fixed in 4.4.0.
  __imag (i = j);

#ifndef __cplusplus
  // A use of the real part
  (float)(ci=ci);
  // Not a use, bug?  gcc treats this as not a use, that's probably a bug due to
  // tree folding ignoring volatile.
  (int)(ci=ci);
#endif

  // A use.
  (float)(i=i);
  // A use.  gcc treats this as not a use, that's probably a bug due to tree
  // folding ignoring volatile.
  (int)(i=i);

  // A use.
  -(i=j);
  // A use.  gcc treats this a not a use, that's probably a bug due to tree
  // folding ignoring volatile.
  +(i=k);

  // A use. gcc treats this a not a use, that's probably a bug due to tree
  // folding ignoring volatile.
  __real (ci=ci);

  // A use.
  i + 0;
  // A use.
  (i=j) + i;
  // A use.  gcc treats this as not a use, that's probably a bug due to tree
  // folding ignoring volatile.
  (i=j) + 0;

#ifdef __cplusplus
  (i,j)=k;
  (j=k,i)=i;
  struct { int x; } s, s1;
  printf("s is at %p\n", &s);
  printf("s is at %p\n", &(s = s1));
  printf("s.x is at %p\n", &((s = s1).x));
#endif
}
OpenPOWER on IntegriCloud