254 lines · c
1// RUN: %clang_analyze_cc1 %s \2// RUN: -Wno-conversion -Wno-tautological-constant-compare \3// RUN: -analyzer-checker=core,apiModeling,unix.StdCLibraryFunctions,alpha.core.Conversion \4// RUN: -verify5 6unsigned char U8;7signed char S8;8 9void assign(unsigned U, signed S) {10 if (S < -10)11 U8 = S; // expected-warning {{Loss of sign in implicit conversion}}12 if (U > 300)13 S8 = U; // expected-warning {{Loss of precision in implicit conversion}}14 if (S > 10)15 U8 = S; // no-warning16 if (U < 200)17 S8 = U; // no-warning18}19 20void addAssign(void) {21 unsigned long L = 1000;22 int I = -100;23 U8 += L; // expected-warning {{Loss of precision in implicit conversion}}24 L += I; // no-warning25}26 27void subAssign(void) {28 unsigned long L = 1000;29 int I = -100;30 U8 -= L; // expected-warning {{Loss of precision in implicit conversion}}31 L -= I; // no-warning32}33 34void mulAssign(void) {35 unsigned long L = 1000;36 int I = -1;37 U8 *= L; // expected-warning {{Loss of precision in implicit conversion}}38 L *= I; // expected-warning {{Loss of sign in implicit conversion}}39 I = 10;40 L *= I; // no-warning41}42 43void divAssign(void) {44 unsigned long L = 1000;45 int I = -1;46 U8 /= L; // no-warning47 L /= I; // expected-warning {{Loss of sign in implicit conversion}}48}49 50void remAssign(void) {51 unsigned long L = 1000;52 int I = -1;53 U8 %= L; // no-warning54 L %= I; // expected-warning {{Loss of sign in implicit conversion}}55}56 57void andAssign(void) {58 unsigned long L = 1000;59 int I = -1;60 U8 &= L; // no-warning61 L &= I; // expected-warning {{Loss of sign in implicit conversion}}62}63 64void orAssign(void) {65 unsigned long L = 1000;66 int I = -1;67 U8 |= L; // expected-warning {{Loss of precision in implicit conversion}}68 L |= I; // expected-warning {{Loss of sign in implicit conversion}}69}70 71void xorAssign(void) {72 unsigned long L = 1000;73 int I = -1;74 U8 ^= L; // expected-warning {{Loss of precision in implicit conversion}}75 L ^= I; // expected-warning {{Loss of sign in implicit conversion}}76}77 78void init1(void) {79 long long A = 1LL << 60;80 short X = A; // expected-warning {{Loss of precision in implicit conversion}}81}82 83void relational(unsigned U, signed S) {84 if (S > 10) {85 if (U < S) { // no-warning86 }87 }88 if (S < -10) {89 if (U < S) { // expected-warning {{Loss of sign in implicit conversion}}90 }91 }92}93 94void multiplication(unsigned U, signed S) {95 if (S > 5)96 S = U * S; // no-warning97 if (S < -10)98 S = U * S; // expected-warning {{Loss of sign}}99}100 101void division(unsigned U, signed S) {102 if (S > 5)103 S = U / S; // no-warning104 if (S < -10)105 S = U / S; // expected-warning {{Loss of sign}}106}107 108void f(unsigned x) {}109void g(unsigned x) {}110 111void functioncall1(void) {112 long x = -1;113 int y = 0;114 f(x); // expected-warning {{Loss of sign in implicit conversion}}115 f(y);116}117 118void functioncall2(int x, int y) {119 if (x < 0)120 f(x); // expected-warning {{Loss of sign in implicit conversion}}121 f(y);122 f(x); // expected-warning {{Loss of sign in implicit conversion}}123}124 125void dontwarn1(unsigned U, signed S) {126 U8 = S; // It might be known that S is always 0x00-0xff.127 S8 = U; // It might be known that U is always 0x00-0xff.128 129 U8 = -1; // Explicit conversion.130 S8 = ~0U; // Explicit conversion.131 if (U > 300)132 U8 &= U; // No loss of precision since there is &=.133}134 135void dontwarn2(unsigned int U) {136 if (U <= 4294967295) {137 }138 if (U <= (2147483647 * 2U + 1U)) {139 }140}141 142void dontwarn3(int X) {143 S8 = X ? 'a' : 'b';144}145 146// don't warn for macros147#define DOSTUFF ({ unsigned X = 1000; U8 = X; })148void dontwarn4(void) {149 DOSTUFF;150}151 152void dontwarn5(void) {153 unsigned char c1 = 'A';154 c1 = (c1 >= 'A' && c1 <= 'Z') ? c1 - 'A' + 'a' : c1;155 unsigned char c2 = 0;156 c2 = (c2 >= 'A' && c2 <= 'Z') ? c2 - 'A' + 'a' : c2;157 unsigned char c3 = 'Z';158 c3 = (c3 >= 'A' && c3 <= 'Z') ? c3 - 'A' + 'a' : c3;159 unsigned char c4 = 'a';160 c4 = (c4 >= 'A' && c4 <= 'Z') ? c4 - 'A' + 'a' : c4;161 unsigned char c5 = '@';162 c5 = (c5 >= 'A' && c5 <= 'Z') ? c5 - 'A' + 'a' : c5;163}164 165void dontwarn6(void) {166 int x = ~0;167 unsigned y = ~0;168}169 170void dontwarn7(unsigned x) {171 if (x == (unsigned)-1) {172 }173}174 175void dontwarn8(void) {176 unsigned x = (unsigned)-1;177}178 179unsigned dontwarn9(void) {180 return ~0;181}182 183char dontwarn10(long long x) {184 long long y = 42;185 y += x;186 return y == 42;187}188 189 190// C library functions, handled via unix.StdCLibraryFunctions191 192int isascii(int c);193void libraryFunction1(void) {194 char kb2[5];195 int X = 1000;196 if (isascii(X)) {197 kb2[0] = X; // no-warning198 }199}200 201 202typedef struct FILE {} FILE; int getc(FILE *stream);203# define EOF (-1)204char reply_string[8192];205FILE *cin;206extern int dostuff(void);207int libraryFunction2(void) {208 int c, n;209 int dig;210 char *cp = reply_string;211 int pflag = 0;212 int code;213 214 for (;;) {215 dig = n = code = 0;216 while ((c = getc(cin)) != '\n') {217 if (dig < 4 && dostuff())218 code = code * 10 + (c - '0');219 if (!pflag && code == 227)220 pflag = 1;221 if (n == 0)222 n = c;223 if (c == EOF)224 return(4);225 if (cp < &reply_string[sizeof(reply_string) - 1])226 *cp++ = c; // no-warning227 }228 }229}230 231double floating_point(long long a, int b) {232 if (a > 1LL << 55) {233 double r = a; // expected-warning {{Loss of precision}}234 return r;235 } else if (b > 1 << 25) {236 float f = b; // expected-warning {{Loss of precision}}237 return f;238 }239 return 137;240}241 242double floating_point2(void) {243 int a = 1 << 24;244 long long b = 1LL << 53;245 float f = a; // no-warning246 double d = b; // no-warning247 return d - f;248}249 250int floating_point_3(unsigned long long a) {251 double b = a; // no-warning252 return 42;253}254