blob: f202696dc623903ee7f7a6fbd2dfd72d497246c4 [file] [log] [blame]
Artem Dergachev002981b2016-08-17 16:02:45 +00001// RUN: %clang_cc1 -Wno-conversion -analyze -analyzer-checker=core,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;
13 if (U < 200)
14 S8 = U;
15}
16
17void init1() {
18 long long A = 1LL << 60;
19 short X = A; // expected-warning {{Loss of precision in implicit conversion}}
20}
21
22void 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
33void 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
40void 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
47void 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
57void dontwarn2(unsigned int U) {
58 if (U <= 4294967295) {
59 }
60 if (U <= (2147483647 * 2U + 1U)) {
61 }
62}
63
64void dontwarn3(int X) {
65 S8 = X ? 'a' : 'b';
66}
67
68// don't warn for macros
69#define DOSTUFF ({ unsigned X = 1000; U8 = X; })
70void 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
77void dontwarn5() {
78 signed S = -32;
79 U8 = S + 10;
80}
81
82
83// false positives..
84
85int isascii(int c);
86void 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
96typedef struct FILE {} FILE; int getc(FILE *stream);
97# define EOF (-1)
98char reply_string[8192];
99FILE *cin;
100extern int dostuff (void);
101int 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