// 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 class TemplateSandwich { // expected-warning{{Excessive padding in 'class TemplateSandwich' instantiated here}} char c1; T t; char c2; }; template class TemplateSandwich { // expected-warning{{Excessive padding in 'class TemplateSandwich' instantiated here}} char c1; T *t; char c2; }; template <> class TemplateSandwich { // expected-warning{{Excessive padding in 'class TemplateSandwich' (}} char c1; long long t; char c2; }; class Holder1 { // no-warning TemplateSandwich t1; TemplateSandwich t2; TemplateSandwich 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 struct Foo { // expected-warning@+1{{Excessive padding in 'struct Foo::Nested'}} struct Nested { char c1; T t; char c2; }; }; struct Holder { // no-warning Foo::Nested t1; Foo::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