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