Clang Project

clang_source_code/test/Analysis/conversion.c
1// RUN: %clang_analyze_cc1 -Wno-conversion -Wno-tautological-constant-compare -analyzer-checker=core,apiModeling,alpha.core.Conversion -verify %s
2
3unsigned char U8;
4signed char S8;
5
6void assign(unsigned U, signed S) {
7  if (S < -10)
8    U8 = S; // expected-warning {{Loss of sign in implicit conversion}}
9  if (U > 300)
10    S8 = U; // expected-warning {{Loss of precision in implicit conversion}}
11  if (S > 10)
12    U8 = S; // no-warning
13  if (U < 200)
14    S8 = U; // no-warning
15}
16
17void addAssign() {
18  unsigned long L = 1000;
19  int I = -100;
20  U8 += L; // expected-warning {{Loss of precision in implicit conversion}}
21  L += I; // no-warning
22}
23
24void subAssign() {
25  unsigned long L = 1000;
26  int I = -100;
27  U8 -= L; // expected-warning {{Loss of precision in implicit conversion}}
28  L -= I; // no-warning
29}
30
31void mulAssign() {
32  unsigned long L = 1000;
33  int I = -1;
34  U8 *= L; // expected-warning {{Loss of precision in implicit conversion}}
35  L *= I;  // expected-warning {{Loss of sign in implicit conversion}}
36  I = 10;
37  L *= I; // no-warning
38}
39
40void divAssign() {
41  unsigned long L = 1000;
42  int I = -1;
43  U8 /= L; // no-warning
44  L /= I; // expected-warning {{Loss of sign in implicit conversion}}
45}
46
47void remAssign() {
48  unsigned long L = 1000;
49  int I = -1;
50  U8 %= L; // no-warning
51  L %= I; // expected-warning {{Loss of sign in implicit conversion}}
52}
53
54void andAssign() {
55  unsigned long L = 1000;
56  int I = -1;
57  U8 &= L; // no-warning
58  L &= I; // expected-warning {{Loss of sign in implicit conversion}}
59}
60
61void orAssign() {
62  unsigned long L = 1000;
63  int I = -1;
64  U8 |= L; // expected-warning {{Loss of precision in implicit conversion}}
65  L |= I;  // expected-warning {{Loss of sign in implicit conversion}}
66}
67
68void xorAssign() {
69  unsigned long L = 1000;
70  int I = -1;
71  U8 ^= L; // expected-warning {{Loss of precision in implicit conversion}}
72  L ^= I;  // expected-warning {{Loss of sign in implicit conversion}}
73}
74
75void init1() {
76  long long A = 1LL << 60;
77  short X = A; // expected-warning {{Loss of precision in implicit conversion}}
78}
79
80void relational(unsigned U, signed S) {
81  if (S > 10) {
82    if (U < S) { // no-warning
83    }
84  }
85  if (S < -10) {
86    if (U < S) { // expected-warning {{Loss of sign in implicit conversion}}
87    }
88  }
89}
90
91void multiplication(unsigned U, signed S) {
92  if (S > 5)
93    S = U * S; // no-warning
94  if (S < -10)
95    S = U * S; // expected-warning {{Loss of sign}}
96}
97
98void division(unsigned U, signed S) {
99  if (S > 5)
100    S = U / S; // no-warning
101  if (S < -10)
102    S = U / S; // expected-warning {{Loss of sign}}
103}
104
105void dontwarn1(unsigned U, signed S) {
106  U8 = S; // It might be known that S is always 0x00-0xff.
107  S8 = U; // It might be known that U is always 0x00-0xff.
108
109  U8 = -1;  // Explicit conversion.
110  S8 = ~0U; // Explicit conversion.
111  if (U > 300)
112    U8 &= U; // No loss of precision since there is &=.
113}
114
115void dontwarn2(unsigned int U) {
116  if (U <= 4294967295) {
117  }
118  if (U <= (2147483647 * 2U + 1U)) {
119  }
120}
121
122void dontwarn3(int X) {
123  S8 = X ? 'a' : 'b';
124}
125
126// don't warn for macros
127#define DOSTUFF ({ unsigned X = 1000; U8 = X; })
128void dontwarn4() {
129  DOSTUFF;
130}
131
132// don't warn for calculations
133// seen some fp. For instance:  c2 = (c2 >= 'A' && c2 <= 'Z') ? c2 - 'A' + 'a' : c2;
134// there is a todo in the checker to handle calculations
135void dontwarn5() {
136  signed S = -32;
137  U8 = S + 10;
138}
139
140char dontwarn6(long long x) {
141  long long y = 42;
142  y += x;
143  return y == 42;
144}
145
146
147// C library functions, handled via apiModeling.StdCLibraryFunctions
148
149int isascii(int c);
150void libraryFunction1() {
151  char kb2[5];
152  int X = 1000;
153  if (isascii(X)) {
154    kb2[0] = X; // no-warning
155  }
156}
157
158
159typedef struct FILE {} FILE; int getc(FILE *stream);
160# define EOF (-1)
161char reply_string[8192];
162FILE *cin;
163extern int dostuff(void);
164int libraryFunction2() {
165  int c, n;
166  int dig;
167  char *cp = reply_string;
168  int pflag = 0;
169  int code;
170
171  for (;;) {
172    dig = n = code = 0;
173    while ((c = getc(cin)) != '\n') {
174      if (dig < 4 && dostuff())
175        code = code * 10 + (c - '0');
176      if (!pflag && code == 227)
177        pflag = 1;
178      if (n == 0)
179        n = c;
180      if (c == EOF)
181        return(4);
182      if (cp < &reply_string[sizeof(reply_string) - 1])
183        *cp++ = c; // no-warning
184    }
185  }
186}
187
188double floating_point(long long a, int b) {
189  if (a > 1LL << 55) {
190    double r = a; // expected-warning {{Loss of precision}}
191    return r;
192  } else if (b > 1 << 25) {
193    float f = b; // expected-warning {{Loss of precision}}
194    return f;
195  }
196  return 137;
197}
198
199double floating_point2() {
200  int a = 1 << 24;
201  long long b = 1LL << 53;
202  float f = a; // no-warning
203  double d = b; // no-warning
204  return d - f;
205}
206
207int floating_point_3(unsigned long long a) {
208  double b = a; // no-warning
209  return 42;
210}
211