xref: /llvm-project/clang/test/Analysis/flexible-array-member.cpp (revision e3e9082b013ba948e3df6d4a2536df9d04656e76)
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++11 -verify %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s
3 
4 #include "Inputs/system-header-simulator-cxx.h"
5 
6 void clang_analyzer_eval(bool);
7 
8 struct S
9 {
10     static int c;
11     static int d;
12     int x;
SS13     S() { x = c++; }
~SS14     ~S() { d++; }
15 };
16 
17 int S::c = 0;
18 int S::d = 0;
19 
20 struct Flex
21 {
22     int length;
23     S contents[0];
24 };
25 
flexibleArrayMember()26 void flexibleArrayMember()
27 {
28     S::c = 0;
29     S::d = 0;
30 
31     const int size = 4;
32 
33     Flex *arr =
34         (Flex *)::operator new(__builtin_offsetof(Flex, contents) + sizeof(S) * size);
35 
36     clang_analyzer_eval(S::c == 0); // expected-warning{{TRUE}}
37 
38     new (&arr->contents[0]) S;
39     new (&arr->contents[1]) S;
40     new (&arr->contents[2]) S;
41     new (&arr->contents[3]) S;
42 
43     clang_analyzer_eval(S::c == size); // expected-warning{{TRUE}}
44 
45     clang_analyzer_eval(arr->contents[0].x == 0); // expected-warning{{TRUE}}
46     clang_analyzer_eval(arr->contents[1].x == 1); // expected-warning{{TRUE}}
47     clang_analyzer_eval(arr->contents[2].x == 2); // expected-warning{{TRUE}}
48     clang_analyzer_eval(arr->contents[3].x == 3); // expected-warning{{TRUE}}
49 
50     arr->contents[0].~S();
51     arr->contents[1].~S();
52     arr->contents[2].~S();
53     arr->contents[3].~S();
54 
55     ::operator delete(arr);
56 
57     clang_analyzer_eval(S::d == size); // expected-warning{{TRUE}}
58 }
59