| // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++11 -verify %s |
| // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s |
| |
| #include "Inputs/system-header-simulator-cxx.h" |
| |
| void clang_analyzer_eval(bool); |
| |
| struct S |
| { |
| static int c; |
| static int d; |
| int x; |
| S() { x = c++; } |
| ~S() { d++; } |
| }; |
| |
| int S::c = 0; |
| int S::d = 0; |
| |
| struct Flex |
| { |
| int length; |
| S contents[0]; |
| }; |
| |
| void flexibleArrayMember() |
| { |
| S::c = 0; |
| S::d = 0; |
| |
| const int size = 4; |
| |
| Flex *arr = |
| (Flex *)::operator new(__builtin_offsetof(Flex, contents) + sizeof(S) * size); |
| |
| clang_analyzer_eval(S::c == 0); // expected-warning{{TRUE}} |
| |
| new (&arr->contents[0]) S; |
| new (&arr->contents[1]) S; |
| new (&arr->contents[2]) S; |
| new (&arr->contents[3]) S; |
| |
| clang_analyzer_eval(S::c == size); // expected-warning{{TRUE}} |
| |
| clang_analyzer_eval(arr->contents[0].x == 0); // expected-warning{{TRUE}} |
| clang_analyzer_eval(arr->contents[1].x == 1); // expected-warning{{TRUE}} |
| clang_analyzer_eval(arr->contents[2].x == 2); // expected-warning{{TRUE}} |
| clang_analyzer_eval(arr->contents[3].x == 3); // expected-warning{{TRUE}} |
| |
| arr->contents[0].~S(); |
| arr->contents[1].~S(); |
| arr->contents[2].~S(); |
| arr->contents[3].~S(); |
| |
| ::operator delete(arr); |
| |
| clang_analyzer_eval(S::d == size); // expected-warning{{TRUE}} |
| } |