2018-10-03 04:50:40 +08:00
|
|
|
// RUN: %clang_analyze_cc1 -Wno-conversion -Wno-tautological-constant-compare -analyzer-checker=core,apiModeling,alpha.core.Conversion -verify %s
|
2016-08-18 00:02:45 +08:00
|
|
|
|
|
|
|
unsigned char U8;
|
|
|
|
signed char S8;
|
|
|
|
|
|
|
|
void assign(unsigned U, signed S) {
|
|
|
|
if (S < -10)
|
|
|
|
U8 = S; // expected-warning {{Loss of sign in implicit conversion}}
|
|
|
|
if (U > 300)
|
|
|
|
S8 = U; // expected-warning {{Loss of precision in implicit conversion}}
|
|
|
|
if (S > 10)
|
2017-04-05 16:57:04 +08:00
|
|
|
U8 = S; // no-warning
|
2016-08-18 00:02:45 +08:00
|
|
|
if (U < 200)
|
2017-04-05 16:57:04 +08:00
|
|
|
S8 = U; // no-warning
|
|
|
|
}
|
|
|
|
|
|
|
|
void addAssign() {
|
|
|
|
unsigned long L = 1000;
|
|
|
|
int I = -100;
|
|
|
|
U8 += L; // expected-warning {{Loss of precision in implicit conversion}}
|
|
|
|
L += I; // no-warning
|
|
|
|
}
|
|
|
|
|
|
|
|
void subAssign() {
|
|
|
|
unsigned long L = 1000;
|
|
|
|
int I = -100;
|
|
|
|
U8 -= L; // expected-warning {{Loss of precision in implicit conversion}}
|
|
|
|
L -= I; // no-warning
|
|
|
|
}
|
|
|
|
|
|
|
|
void mulAssign() {
|
|
|
|
unsigned long L = 1000;
|
|
|
|
int I = -1;
|
|
|
|
U8 *= L; // expected-warning {{Loss of precision in implicit conversion}}
|
|
|
|
L *= I; // expected-warning {{Loss of sign in implicit conversion}}
|
|
|
|
I = 10;
|
|
|
|
L *= I; // no-warning
|
|
|
|
}
|
|
|
|
|
|
|
|
void divAssign() {
|
|
|
|
unsigned long L = 1000;
|
|
|
|
int I = -1;
|
|
|
|
U8 /= L; // no-warning
|
|
|
|
L /= I; // expected-warning {{Loss of sign in implicit conversion}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void remAssign() {
|
|
|
|
unsigned long L = 1000;
|
|
|
|
int I = -1;
|
|
|
|
U8 %= L; // no-warning
|
|
|
|
L %= I; // expected-warning {{Loss of sign in implicit conversion}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void andAssign() {
|
|
|
|
unsigned long L = 1000;
|
|
|
|
int I = -1;
|
|
|
|
U8 &= L; // no-warning
|
|
|
|
L &= I; // expected-warning {{Loss of sign in implicit conversion}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void orAssign() {
|
|
|
|
unsigned long L = 1000;
|
|
|
|
int I = -1;
|
|
|
|
U8 |= L; // expected-warning {{Loss of precision in implicit conversion}}
|
|
|
|
L |= I; // expected-warning {{Loss of sign in implicit conversion}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void xorAssign() {
|
|
|
|
unsigned long L = 1000;
|
|
|
|
int I = -1;
|
|
|
|
U8 ^= L; // expected-warning {{Loss of precision in implicit conversion}}
|
|
|
|
L ^= I; // expected-warning {{Loss of sign in implicit conversion}}
|
2016-08-18 00:02:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void init1() {
|
|
|
|
long long A = 1LL << 60;
|
|
|
|
short X = A; // expected-warning {{Loss of precision in implicit conversion}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void relational(unsigned U, signed S) {
|
|
|
|
if (S > 10) {
|
2017-04-05 16:57:04 +08:00
|
|
|
if (U < S) { // no-warning
|
2016-08-18 00:02:45 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (S < -10) {
|
|
|
|
if (U < S) { // expected-warning {{Loss of sign in implicit conversion}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void multiplication(unsigned U, signed S) {
|
|
|
|
if (S > 5)
|
2017-04-05 16:57:04 +08:00
|
|
|
S = U * S; // no-warning
|
2016-08-18 00:02:45 +08:00
|
|
|
if (S < -10)
|
|
|
|
S = U * S; // expected-warning {{Loss of sign}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void division(unsigned U, signed S) {
|
|
|
|
if (S > 5)
|
2017-04-05 16:57:04 +08:00
|
|
|
S = U / S; // no-warning
|
2016-08-18 00:02:45 +08:00
|
|
|
if (S < -10)
|
|
|
|
S = U / S; // expected-warning {{Loss of sign}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void dontwarn1(unsigned U, signed S) {
|
|
|
|
U8 = S; // It might be known that S is always 0x00-0xff.
|
|
|
|
S8 = U; // It might be known that U is always 0x00-0xff.
|
|
|
|
|
|
|
|
U8 = -1; // Explicit conversion.
|
|
|
|
S8 = ~0U; // Explicit conversion.
|
|
|
|
if (U > 300)
|
|
|
|
U8 &= U; // No loss of precision since there is &=.
|
|
|
|
}
|
|
|
|
|
|
|
|
void dontwarn2(unsigned int U) {
|
|
|
|
if (U <= 4294967295) {
|
|
|
|
}
|
|
|
|
if (U <= (2147483647 * 2U + 1U)) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void dontwarn3(int X) {
|
|
|
|
S8 = X ? 'a' : 'b';
|
|
|
|
}
|
|
|
|
|
|
|
|
// don't warn for macros
|
|
|
|
#define DOSTUFF ({ unsigned X = 1000; U8 = X; })
|
|
|
|
void dontwarn4() {
|
|
|
|
DOSTUFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
// don't warn for calculations
|
|
|
|
// seen some fp. For instance: c2 = (c2 >= 'A' && c2 <= 'Z') ? c2 - 'A' + 'a' : c2;
|
|
|
|
// there is a todo in the checker to handle calculations
|
|
|
|
void dontwarn5() {
|
|
|
|
signed S = -32;
|
|
|
|
U8 = S + 10;
|
|
|
|
}
|
|
|
|
|
2018-11-16 09:00:55 +08:00
|
|
|
char dontwarn6(long long x) {
|
|
|
|
long long y = 42;
|
|
|
|
y += x;
|
|
|
|
return y == 42;
|
|
|
|
}
|
|
|
|
|
2016-08-18 00:02:45 +08:00
|
|
|
|
2018-10-03 04:50:40 +08:00
|
|
|
// C library functions, handled via apiModeling.StdCLibraryFunctions
|
2016-08-18 00:02:45 +08:00
|
|
|
|
|
|
|
int isascii(int c);
|
2018-10-03 04:50:40 +08:00
|
|
|
void libraryFunction1() {
|
2016-08-18 00:02:45 +08:00
|
|
|
char kb2[5];
|
|
|
|
int X = 1000;
|
|
|
|
if (isascii(X)) {
|
2018-10-03 04:50:40 +08:00
|
|
|
kb2[0] = X; // no-warning
|
2016-08-18 00:02:45 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct FILE {} FILE; int getc(FILE *stream);
|
|
|
|
# define EOF (-1)
|
|
|
|
char reply_string[8192];
|
|
|
|
FILE *cin;
|
2018-11-16 09:00:55 +08:00
|
|
|
extern int dostuff(void);
|
2018-10-03 04:50:40 +08:00
|
|
|
int libraryFunction2() {
|
2016-08-18 00:02:45 +08:00
|
|
|
int c, n;
|
|
|
|
int dig;
|
|
|
|
char *cp = reply_string;
|
|
|
|
int pflag = 0;
|
|
|
|
int code;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
dig = n = code = 0;
|
|
|
|
while ((c = getc(cin)) != '\n') {
|
|
|
|
if (dig < 4 && dostuff())
|
|
|
|
code = code * 10 + (c - '0');
|
|
|
|
if (!pflag && code == 227)
|
|
|
|
pflag = 1;
|
|
|
|
if (n == 0)
|
|
|
|
n = c;
|
|
|
|
if (c == EOF)
|
|
|
|
return(4);
|
|
|
|
if (cp < &reply_string[sizeof(reply_string) - 1])
|
2018-10-03 04:50:40 +08:00
|
|
|
*cp++ = c; // no-warning
|
2016-08-18 00:02:45 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-16 09:00:55 +08:00
|
|
|
double floating_point(long long a, int b) {
|
|
|
|
if (a > 1LL << 55) {
|
|
|
|
double r = a; // expected-warning {{Loss of precision}}
|
|
|
|
return r;
|
|
|
|
} else if (b > 1 << 25) {
|
|
|
|
float f = b; // expected-warning {{Loss of precision}}
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
return 137;
|
|
|
|
}
|
|
|
|
|
|
|
|
double floating_point2() {
|
|
|
|
int a = 1 << 24;
|
|
|
|
long long b = 1LL << 53;
|
|
|
|
float f = a; // no-warning
|
|
|
|
double d = b; // no-warning
|
|
|
|
return d - f;
|
|
|
|
}
|
|
|
|
|
|
|
|
int floating_point_3(unsigned long long a) {
|
|
|
|
double b = a; // no-warning
|
|
|
|
return 42;
|
|
|
|
}
|