1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -verify %s \
// RUN: -analyzer-checker=core,debug.ExprInspection,alpha.core.BoolAssignment
#define __UINT_MAX__ (__INT_MAX__ * 2U + 1U)
#define __INT_MIN__ (-__INT_MAX__ - 1)
void clang_analyzer_dump_int(int);
void clang_analyzer_dump_long(long);
void clang_analyzer_eval(int);
void clang_analyzer_warnIfReached(void);
void test_add_nooverflow(void)
{
int res;
if (__builtin_add_overflow(10, 20, &res)) {
clang_analyzer_warnIfReached();
return;
}
clang_analyzer_dump_int(res); //expected-warning{{30 S32b}}
}
void test_add_overflow(void)
{
int res;
if (__builtin_add_overflow(__INT_MAX__, 1, &res)) {
clang_analyzer_dump_int(res); //expected-warning{{-2147483648 S32b}}
return;
}
clang_analyzer_warnIfReached();
}
void test_add_underoverflow(void)
{
int res;
if (__builtin_add_overflow(__INT_MIN__, -1, &res)) {
clang_analyzer_dump_int(res); //expected-warning{{2147483647 S32b}}
return;
}
clang_analyzer_warnIfReached();
}
void test_sub_underflow(void)
{
int res;
if (__builtin_sub_overflow(__INT_MIN__, 10, &res)) {
return;
}
clang_analyzer_warnIfReached();
}
void test_sub_overflow(void)
{
int res;
if (__builtin_sub_overflow(__INT_MAX__, -1, &res)) {
return;
}
clang_analyzer_warnIfReached();
}
void test_sub_nooverflow(void)
{
int res;
if (__builtin_sub_overflow(__INT_MAX__, 1, &res)) {
clang_analyzer_warnIfReached();
return;
}
clang_analyzer_dump_int(res); //expected-warning{{2147483646 S32b}}
}
void test_mul_overflow(void)
{
int res;
if (__builtin_mul_overflow(__INT_MAX__, 2, &res)) {
return;
}
clang_analyzer_warnIfReached();
}
void test_mul_underflow(void)
{
int res;
if (__builtin_mul_overflow(__INT_MIN__, -2, &res)) {
return;
}
clang_analyzer_warnIfReached();
}
void test_mul_nooverflow(void)
{
int res;
if (__builtin_mul_overflow(10, -2, &res)) {
clang_analyzer_warnIfReached();
return;
}
clang_analyzer_dump_int(res); //expected-warning{{-20 S32b}}
}
void test_nooverflow_diff_types(void)
{
long res;
// This is not an overflow, since result type is long.
if (__builtin_add_overflow(__INT_MAX__, 1, &res)) {
clang_analyzer_warnIfReached();
return;
}
clang_analyzer_dump_long(res); //expected-warning{{2147483648 S64b}}
}
void test_uaddll_overflow_contraints(unsigned long a, unsigned long b)
{
unsigned long long res;
if (a != 10)
return;
if (b != 10)
return;
if (__builtin_uaddll_overflow(a, b, &res)) {
clang_analyzer_warnIfReached();
return;
}
}
void test_uadd_overflow_contraints(unsigned a, unsigned b)
{
unsigned res;
if (a > 5)
return;
if (b != 10)
return;
if (__builtin_uadd_overflow(a, b, &res)) {
clang_analyzer_warnIfReached();
return;
}
}
void test_bool_assign(void)
{
int res;
// Reproduce issue from GH#111147. __builtin_*_overflow functions
// should return _Bool, but not int.
_Bool ret = __builtin_mul_overflow(10, 20, &res); // no crash
}
|