]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Analysis/conversion.c
Vendor import of clang trunk r290819:
[FreeBSD/FreeBSD.git] / test / Analysis / conversion.c
1 // RUN: %clang_cc1 -Wno-conversion -analyze -analyzer-checker=core,alpha.core.Conversion -verify %s
2
3 unsigned char U8;
4 signed char S8;
5
6 void 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;
13   if (U < 200)
14     S8 = U;
15 }
16
17 void init1() {
18   long long A = 1LL << 60;
19   short X = A; // expected-warning {{Loss of precision in implicit conversion}}
20 }
21
22 void relational(unsigned U, signed S) {
23   if (S > 10) {
24     if (U < S) {
25     }
26   }
27   if (S < -10) {
28     if (U < S) { // expected-warning {{Loss of sign in implicit conversion}}
29     }
30   }
31 }
32
33 void multiplication(unsigned U, signed S) {
34   if (S > 5)
35     S = U * S;
36   if (S < -10)
37     S = U * S; // expected-warning {{Loss of sign}}
38 }
39
40 void division(unsigned U, signed S) {
41   if (S > 5)
42     S = U / S;
43   if (S < -10)
44     S = U / S; // expected-warning {{Loss of sign}}
45 }
46
47 void dontwarn1(unsigned U, signed S) {
48   U8 = S; // It might be known that S is always 0x00-0xff.
49   S8 = U; // It might be known that U is always 0x00-0xff.
50
51   U8 = -1;  // Explicit conversion.
52   S8 = ~0U; // Explicit conversion.
53   if (U > 300)
54     U8 &= U; // No loss of precision since there is &=.
55 }
56
57 void dontwarn2(unsigned int U) {
58   if (U <= 4294967295) {
59   }
60   if (U <= (2147483647 * 2U + 1U)) {
61   }
62 }
63
64 void dontwarn3(int X) {
65   S8 = X ? 'a' : 'b';
66 }
67
68 // don't warn for macros
69 #define DOSTUFF ({ unsigned X = 1000; U8 = X; })
70 void dontwarn4() {
71   DOSTUFF;
72 }
73
74 // don't warn for calculations
75 // seen some fp. For instance:  c2 = (c2 >= 'A' && c2 <= 'Z') ? c2 - 'A' + 'a' : c2;
76 // there is a todo in the checker to handle calculations
77 void dontwarn5() {
78   signed S = -32;
79   U8 = S + 10;
80 }
81
82
83 // false positives..
84
85 int isascii(int c);
86 void falsePositive1() {
87   char kb2[5];
88   int X = 1000;
89   if (isascii(X)) {
90     // FIXME: should not warn here:
91     kb2[0] = X; // expected-warning {{Loss of precision}}
92   }
93 }
94
95
96 typedef struct FILE {} FILE; int getc(FILE *stream);
97 # define EOF (-1)
98 char reply_string[8192];
99 FILE *cin;
100 extern int dostuff (void);
101 int falsePositive2() {
102   int c, n;
103   int dig;
104   char *cp = reply_string;
105   int pflag = 0;
106   int code;
107
108   for (;;) {
109     dig = n = code = 0;
110     while ((c = getc(cin)) != '\n') {
111       if (dig < 4 && dostuff())
112         code = code * 10 + (c - '0');
113       if (!pflag && code == 227)
114         pflag = 1;
115       if (n == 0)
116         n = c;
117       if (c == EOF)
118         return(4);
119       if (cp < &reply_string[sizeof(reply_string) - 1])
120         // FIXME: should not warn here:
121         *cp++ = c; // expected-warning {{Loss of precision}}
122     }
123   }
124 }
125