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