1 // RUN: %clang_analyze_cc1 -Wno-conversion -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 126