1 // RUN: %clang_cc1 -std=c++14 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s 2 3 // Make sure that the C cases still work fine, even when compiled as C++. 4 #include "padding_c.c" 5 6 struct BigCharArray2 { // no-warning 7 char c[129]; 8 }; 9 10 // xxxexpected-warning@+1{{Excessive padding in 'struct LowAlignmentBase'}} 11 struct LowAlignmentBase : public BigCharArray2 { 12 int i; 13 char c; 14 }; 15 16 struct CorrectLowAlignmentBase : public BigCharArray2 { // no-warning 17 char c; 18 int i; 19 }; 20 21 // xxxexpected-warning@+1{{Excessive padding in 'struct LowAlignmentBase2'}} 22 struct LowAlignmentBase2 : public BigCharArray2 { 23 char c1; 24 int i; 25 char c2; 26 }; 27 28 class PaddedA { // expected-warning{{Excessive padding in 'class PaddedA'}} 29 char c1; 30 int i; 31 char c2; 32 }; 33 34 class VirtualPaddedA : public PaddedA { // no-warning foo()35 virtual void foo() {} 36 }; 37 38 class VirtualIntSandwich { // expected-warning{{Excessive padding in 'class VirtualIntSandwich'}} foo()39 virtual void foo() {} 40 char c1; 41 int i; 42 char c2; 43 }; 44 45 // constructed so as not to have tail padding 46 class InnerPaddedB { // expected-warning{{Excessive padding in 'class InnerPaddedB'}} 47 char c1; 48 int i1; 49 char c2; 50 int i2; 51 }; 52 53 class TailPaddedB { // expected-warning{{Excessive padding in 'class TailPaddedB'}} 54 char c1; 55 int i1; 56 char c2; 57 }; 58 59 class SI : public PaddedA { // no-warning 60 char c; 61 }; 62 63 class SI2 : public PaddedA { // xxxexpected-warning{{Excessive padding in 'class SI2'}} 64 char c10; 65 int i10; 66 char c11; 67 }; 68 69 class VirtualSI : virtual public PaddedA { // no-warning 70 char c; 71 }; 72 73 // currently not checked for 74 class VirtualSI2 : virtual public PaddedA { // no-warning 75 char c10; 76 int i10; 77 char c11; 78 }; 79 80 class VtblSI : public PaddedA { // no-warning foo()81 virtual void foo() {} 82 char c; 83 }; 84 85 class VtblSI2 : public PaddedA { // xxxexpected-warning{{Excessive padding in 'class VtblSI2'}} foo()86 virtual void foo() {} 87 char c10; 88 int i10; 89 char c11; 90 }; 91 92 class VtblSI3 : public VirtualPaddedA { // xxxexpected-warning{{Excessive padding in 'class VtblSI3'}} 93 char c10; 94 int i10; 95 char c11; 96 }; 97 98 class MI : public PaddedA, public InnerPaddedB { // no-warning 99 char c; 100 }; 101 102 class MI2 : public PaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class MI2'}} 103 char c10; 104 int i10; 105 char c11; 106 }; 107 108 class VtblMI : public PaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class VtblMI'}} foo()109 virtual void foo() {} 110 char c10; 111 int i10; 112 char c11; 113 }; 114 115 class VtblMI2 : public VirtualPaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class VtblMI2'}} 116 char c10; 117 int i10; 118 char c11; 119 }; 120 121 class Empty {}; // no-warning 122 123 class LotsOfSpace { // expected-warning{{Excessive padding in 'class LotsOfSpace'}} 124 Empty e1; 125 int i; 126 Empty e2; 127 }; 128 129 class EBO1 : public Empty { // xxxexpected-warning{{Excessive padding in 'class EBO1'}} 130 char c1; 131 int i; 132 char c2; 133 }; 134 135 class EBO2 : public Empty { // xxxexpected-warning{{Excessive padding in 'class EBO2'}} 136 Empty c1; 137 int i; 138 Empty c2; 139 }; 140 141 template <typename T> 142 class TemplateSandwich { // expected-warning{{Excessive padding in 'class TemplateSandwich<int>' instantiated here}} 143 char c1; 144 T t; 145 char c2; 146 }; 147 148 template <typename T> 149 class TemplateSandwich<T *> { // expected-warning{{Excessive padding in 'class TemplateSandwich<void *>' instantiated here}} 150 char c1; 151 T *t; 152 char c2; 153 }; 154 155 template <> 156 class TemplateSandwich<long long> { // expected-warning{{Excessive padding in 'class TemplateSandwich<long long>' (}} 157 char c1; 158 long long t; 159 char c2; 160 }; 161 162 class Holder1 { // no-warning 163 TemplateSandwich<int> t1; 164 TemplateSandwich<char> t2; 165 TemplateSandwich<void *> t3; 166 }; 167 168 typedef struct { // expected-warning{{Excessive padding in 'TypedefSandwich2'}} 169 char c1; 170 typedef struct { // expected-warning{{Excessive padding in 'TypedefSandwich2::NestedTypedef'}} 171 char c1; 172 int i; 173 char c2; 174 } NestedTypedef; 175 NestedTypedef t; 176 char c2; 177 } TypedefSandwich2; 178 179 template <typename T> 180 struct Foo { 181 // expected-warning@+1{{Excessive padding in 'struct Foo<int>::Nested'}} 182 struct Nested { 183 char c1; 184 T t; 185 char c2; 186 }; 187 }; 188 189 struct Holder { // no-warning 190 Foo<int>::Nested t1; 191 Foo<char>::Nested t2; 192 }; 193 194 struct GlobalsForLambda { // no-warning 195 int i; 196 char c1; 197 char c2; 198 } G; 199 200 // expected-warning@+1{{Excessive padding in 'class (lambda}} __anon9362a8960302null201auto lambda1 = [ c1 = G.c1, i = G.i, c2 = G.c2 ]{}; __anon9362a8960402null202auto lambda2 = [ i = G.i, c1 = G.c1, c2 = G.c2 ]{}; // no-warning 203