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