blob: fe77623310023a91f086c0fa6334660c8f35ae6e [file] [edit]
// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux-gnu -analyzer-checker=core,debug.ExprInspection -verify=expected,c -xc %s
// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux-gnu -analyzer-checker=core,debug.ExprInspection -verify=expected,cpp -xc++ -DCPP -std=c++14 %s
void clang_analyzer_value(int);
struct CStruct {
int a;
};
struct CStruct nonconst_c_struct_array[1] = {
{11},
};
void use_nonconst_struct_array_c(void) {
clang_analyzer_value(nonconst_c_struct_array->a); // expected-warning {{32s:{ [-2147483648, 2147483647] }}}
}
const struct CStruct const_c_struct_array[1] = { {22} };
void use_const_struct_array_c(void) {
clang_analyzer_value(const_c_struct_array->a); // expected-warning {{22}}
}
#ifdef CPP
struct CPPStruct {
int a = 33;
};
CPPStruct nonconst_cpp_struct_array[1] = {};
const CPPStruct const_cpp_struct_array[1] = {};
struct CPPStructWithUserCtor {
int a = 44;
CPPStructWithUserCtor(): a(55) {}
};
CPPStructWithUserCtor nonconst_cpp_struct_wctor_array[1] = {};
void use_nonconst_struct_array_cpp(void) {
clang_analyzer_value(nonconst_cpp_struct_array->a); // cpp-warning {{32s:{ [-2147483648, 2147483647] }}}
}
const CPPStructWithUserCtor const_cpp_struct_wctor_array[1] = {};
#endif
int main(int argc, char **argv) {
// FIXME: In C++ mode, IsMainAnalysis is false because global constructors
// may run before main(), so the initializer for non-const globals are not
// considered. In C mode this correctly resolves to 11.
clang_analyzer_value(nonconst_c_struct_array->a); // c-warning {{11}} cpp-warning {{32s:{ [-2147483648, 2147483647] }}}
#ifdef CPP
// Default member initialization is resolved from the initializer.
clang_analyzer_value(const_cpp_struct_array->a); // cpp-warning {{33}}
// FIXME: In C++ mode, non-const globals are not trusted because global
// constructors may run before main(). This should be 33.
clang_analyzer_value(nonconst_cpp_struct_array->a); // cpp-warning {{32s:{ [-2147483648, 2147483647] }}}
// FIXME: We do not model constructor calls in initializers. This should
// be 55 (from the constructor's initializer list).
clang_analyzer_value(const_cpp_struct_wctor_array->a); // cpp-warning {{32s:{ [-2147483648, 2147483647] }}}
// FIXME: Non-const global in C++ mode, and also requires modeling
// constructor calls. This should be 55.
clang_analyzer_value(nonconst_cpp_struct_wctor_array->a); // cpp-warning {{32s:{ [-2147483648, 2147483647] }}}
#endif
}
struct Inner {
int x;
int y;
};
struct Outer {
struct Inner arr[2];
int z;
};
const struct Outer nested = {{{10, 20}, {30, 40}}, 50};
void test_nested_struct_array_field(void) {
clang_analyzer_value(nested.arr[0].x); // expected-warning {{10}}
clang_analyzer_value(nested.arr[0].y); // expected-warning {{20}}
clang_analyzer_value(nested.arr[1].x); // expected-warning {{30}}
clang_analyzer_value(nested.arr[1].y); // expected-warning {{40}}
clang_analyzer_value(nested.z); // expected-warning {{50}}
}
// Elided braces: see [dcl.init.aggr] p15.
const struct Outer nested_elided = {10, 20, 30, 40, 50};
void test_nested_elided_braces(void) {
clang_analyzer_value(nested_elided.arr[0].x); // expected-warning {{10}}
clang_analyzer_value(nested_elided.arr[0].y); // expected-warning {{20}}
clang_analyzer_value(nested_elided.arr[1].x); // expected-warning {{30}}
clang_analyzer_value(nested_elided.arr[1].y); // expected-warning {{40}}
clang_analyzer_value(nested_elided.z); // expected-warning {{50}}
}
const struct CStruct matrix[2][2] = {{{1}, {2}}, {{3}, {4}}};
void test_2d_array_of_structs(void) {
clang_analyzer_value(matrix[0][0].a); // expected-warning {{1}}
clang_analyzer_value(matrix[0][1].a); // expected-warning {{2}}
clang_analyzer_value(matrix[1][0].a); // expected-warning {{3}}
clang_analyzer_value(matrix[1][1].a); // expected-warning {{4}}
}
const struct CStruct matrix_elided[2][2] = {1, 2, 3, 4};
void test_matrix_elided_braces(void) {
clang_analyzer_value(matrix_elided[0][0].a); // expected-warning {{1}}
clang_analyzer_value(matrix_elided[0][1].a); // expected-warning {{2}}
clang_analyzer_value(matrix_elided[1][0].a); // expected-warning {{3}}
clang_analyzer_value(matrix_elided[1][1].a); // expected-warning {{4}}
}
const struct Inner partial_arr[3] = {{100, 200}};
void test_array_filler_zero_init(void) {
clang_analyzer_value(partial_arr[0].x); // expected-warning {{100}}
clang_analyzer_value(partial_arr[0].y); // expected-warning {{200}}
clang_analyzer_value(partial_arr[1].x); // expected-warning {{0}}
clang_analyzer_value(partial_arr[2].y); // expected-warning {{0}}
}
union IntOrChar {
int i;
char c;
};
const union IntOrChar u_int = {42};
void test_union_active_member(void) {
clang_analyzer_value(u_int.i); // expected-warning {{42}}
}
void test_union_inactive_member(void) {
clang_analyzer_value(u_int.c); // expected-warning {{8s:{ [-128, 127] }}}
}
const union IntOrChar u_char = {.c = 'x'};
void test_union_designated_active(void) {
clang_analyzer_value(u_char.c); // expected-warning {{120}}
}
void test_union_designated_inactive(void) {
clang_analyzer_value(u_char.i); // expected-warning {{32s:{ [-2147483648, 2147483647] }}}
}
struct HasUnion {
union IntOrChar u;
int after;
};
const struct HasUnion hu = {{99}, 7};
void test_union_in_struct(void) {
clang_analyzer_value(hu.u.i); // expected-warning {{99}}
clang_analyzer_value(hu.u.c); // expected-warning {{8s:{ [-128, 127] }}}
clang_analyzer_value(hu.after); // expected-warning {{7}}
}
// Empty initializer zero-initializes the first member.
const union IntOrChar u_empty = {};
void test_union_empty_init(void) {
clang_analyzer_value(u_empty.i); // expected-warning {{0}}
clang_analyzer_value(u_empty.c); // expected-warning {{8s:{ [-128, 127] }}}
}
const union IntOrChar u_arr[2] = {{10}, {.c = 'y'}};
void test_union_array(void) {
clang_analyzer_value(u_arr[0].i); // expected-warning {{10}}
clang_analyzer_value(u_arr[0].c); // expected-warning {{8s:{ [-128, 127] }}}
clang_analyzer_value(u_arr[1].c); // expected-warning {{121}}
clang_analyzer_value(u_arr[1].i); // expected-warning {{32s:{ [-2147483648, 2147483647] }}}
}
struct Tagged {
int tag;
union {
int ival;
char cval;
} payload;
};
const struct Tagged tagged_arr[2] = {
{1, {.ival = 100}},
{2, {.cval = 'Z'}},
};
void test_struct_union_array(void) {
clang_analyzer_value(tagged_arr[0].tag); // expected-warning {{1}}
clang_analyzer_value(tagged_arr[0].payload.ival); // expected-warning {{100}}
clang_analyzer_value(tagged_arr[0].payload.cval); // expected-warning {{8s:{ [-128, 127] }}}
clang_analyzer_value(tagged_arr[1].tag); // expected-warning {{2}}
clang_analyzer_value(tagged_arr[1].payload.cval); // expected-warning {{90}}
clang_analyzer_value(tagged_arr[1].payload.ival); // expected-warning {{32s:{ [-2147483648, 2147483647] }}}
}