| // RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s | |
| // Make sure that the C cases still work fine, even when compiled as C++. | |
| #include "padding_c.c" | |
| struct BigCharArray2 { // no-warning | |
| char c[129]; | |
| }; | |
| // xxxexpected-warning@+1{{Excessive padding in 'struct LowAlignmentBase'}} | |
| struct LowAlignmentBase : public BigCharArray2 { | |
| int i; | |
| char c; | |
| }; | |
| struct CorrectLowAlignmentBase : public BigCharArray2 { // no-warning | |
| char c; | |
| int i; | |
| }; | |
| // xxxexpected-warning@+1{{Excessive padding in 'struct LowAlignmentBase2'}} | |
| struct LowAlignmentBase2 : public BigCharArray2 { | |
| char c1; | |
| int i; | |
| char c2; | |
| }; | |
| class PaddedA { // expected-warning{{Excessive padding in 'class PaddedA'}} | |
| char c1; | |
| int i; | |
| char c2; | |
| }; | |
| class VirtualPaddedA : public PaddedA { // no-warning | |
| virtual void foo() {} | |
| }; | |
| class VirtualIntSandwich { // expected-warning{{Excessive padding in 'class VirtualIntSandwich'}} | |
| virtual void foo() {} | |
| char c1; | |
| int i; | |
| char c2; | |
| }; | |
| // constructed so as not to have tail padding | |
| class InnerPaddedB { // expected-warning{{Excessive padding in 'class InnerPaddedB'}} | |
| char c1; | |
| int i1; | |
| char c2; | |
| int i2; | |
| }; | |
| class TailPaddedB { // expected-warning{{Excessive padding in 'class TailPaddedB'}} | |
| char c1; | |
| int i1; | |
| char c2; | |
| }; | |
| class SI : public PaddedA { // no-warning | |
| char c; | |
| }; | |
| class SI2 : public PaddedA { // xxxexpected-warning{{Excessive padding in 'class SI2'}} | |
| char c10; | |
| int i10; | |
| char c11; | |
| }; | |
| class VirtualSI : virtual public PaddedA { // no-warning | |
| char c; | |
| }; | |
| // currently not checked for | |
| class VirtualSI2 : virtual public PaddedA { // no-warning | |
| char c10; | |
| int i10; | |
| char c11; | |
| }; | |
| class VtblSI : public PaddedA { // no-warning | |
| virtual void foo() {} | |
| char c; | |
| }; | |
| class VtblSI2 : public PaddedA { // xxxexpected-warning{{Excessive padding in 'class VtblSI2'}} | |
| virtual void foo() {} | |
| char c10; | |
| int i10; | |
| char c11; | |
| }; | |
| class VtblSI3 : public VirtualPaddedA { // xxxexpected-warning{{Excessive padding in 'class VtblSI3'}} | |
| char c10; | |
| int i10; | |
| char c11; | |
| }; | |
| class MI : public PaddedA, public InnerPaddedB { // no-warning | |
| char c; | |
| }; | |
| class MI2 : public PaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class MI2'}} | |
| char c10; | |
| int i10; | |
| char c11; | |
| }; | |
| class VtblMI : public PaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class VtblMI'}} | |
| virtual void foo() {} | |
| char c10; | |
| int i10; | |
| char c11; | |
| }; | |
| class VtblMI2 : public VirtualPaddedA, public InnerPaddedB { // xxxexpected-warning{{Excessive padding in 'class VtblMI2'}} | |
| char c10; | |
| int i10; | |
| char c11; | |
| }; | |
| class Empty {}; // no-warning | |
| class LotsOfSpace { // expected-warning{{Excessive padding in 'class LotsOfSpace'}} | |
| Empty e1; | |
| int i; | |
| Empty e2; | |
| }; | |
| class EBO1 : public Empty { // xxxexpected-warning{{Excessive padding in 'class EBO1'}} | |
| char c1; | |
| int i; | |
| char c2; | |
| }; | |
| class EBO2 : public Empty { // xxxexpected-warning{{Excessive padding in 'class EBO2'}} | |
| Empty c1; | |
| int i; | |
| Empty c2; | |
| }; | |
| template <typename T> | |
| class TemplateSandwich { // expected-warning{{Excessive padding in 'class TemplateSandwich<int>' instantiated here}} | |
| char c1; | |
| T t; | |
| char c2; | |
| }; | |
| template <typename T> | |
| class TemplateSandwich<T *> { // expected-warning{{Excessive padding in 'class TemplateSandwich<void *>' instantiated here}} | |
| char c1; | |
| T *t; | |
| char c2; | |
| }; | |
| template <> | |
| class TemplateSandwich<long long> { // expected-warning{{Excessive padding in 'class TemplateSandwich<long long>' (}} | |
| char c1; | |
| long long t; | |
| char c2; | |
| }; | |
| class Holder1 { // no-warning | |
| TemplateSandwich<int> t1; | |
| TemplateSandwich<char> t2; | |
| TemplateSandwich<void *> t3; | |
| }; | |
| typedef struct TypedefSandwich2 { // expected-warning{{Excessive padding in 'struct TypedefSandwich2'}} | |
| char c1; | |
| typedef struct { // expected-warning{{Excessive padding in 'TypedefSandwich2::NestedTypedef'}} | |
| char c1; | |
| int i; | |
| char c2; | |
| } NestedTypedef; | |
| NestedTypedef t; | |
| char c2; | |
| } TypedefSandwich2; | |
| template <typename T> | |
| struct Foo { | |
| // expected-warning@+1{{Excessive padding in 'struct Foo<int>::Nested'}} | |
| struct Nested { | |
| char c1; | |
| T t; | |
| char c2; | |
| }; | |
| }; | |
| struct Holder { // no-warning | |
| Foo<int>::Nested t1; | |
| Foo<char>::Nested t2; | |
| }; | |
| struct GlobalsForLambda { // no-warning | |
| int i; | |
| char c1; | |
| char c2; | |
| } G; | |
| // expected-warning@+1{{Excessive padding in 'class (lambda}} | |
| auto lambda1 = [ c1 = G.c1, i = G.i, c2 = G.c2 ]{}; | |
| auto lambda2 = [ i = G.i, c1 = G.c1, c2 = G.c2 ]{}; // no-warning |