1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
// 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
|