| // 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] }}} | |
| } |