| // Test -fsanitize-address-field-padding | 
 | // RUN: echo 'type:SomeNamespace::BlacklistedByName=field-padding' > %t.type.blacklist | 
 | // RUN: echo 'src:*sanitize-address-field-padding.cpp=field-padding' > %t.file.blacklist | 
 | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsanitize=address -fsanitize-address-field-padding=1 -fsanitize-blacklist=%t.type.blacklist -Rsanitize-address -emit-llvm -o - %s 2>&1 | FileCheck %s | 
 | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsanitize=address -fsanitize-address-field-padding=1 -fsanitize-blacklist=%t.type.blacklist -Rsanitize-address -emit-llvm -o - %s -O1 -mconstructor-aliases 2>&1 | FileCheck %s --check-prefix=WITH_CTOR_ALIASES | 
 | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsanitize=address -fsanitize-address-field-padding=1 -fsanitize-blacklist=%t.file.blacklist -Rsanitize-address -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=FILE_BLACKLIST | 
 | // RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=NO_PADDING | 
 | // Try to emulate -save-temps option and make sure -disable-llvm-passes will not run sanitize instrumentation. | 
 | // RUN: %clang_cc1 -fsanitize=address -emit-llvm -disable-llvm-passes -o - %s | %clang_cc1 -fsanitize=address -emit-llvm -o - -x ir | FileCheck %s --check-prefix=NO_PADDING | 
 | // | 
 |  | 
 | // The reasons to ignore a particular class are not set in stone and will change. | 
 | // | 
 | // CHECK: -fsanitize-address-field-padding applied to Positive1 | 
 | // CHECK: -fsanitize-address-field-padding ignored for Negative1 because it is trivially copyable | 
 | // CHECK: -fsanitize-address-field-padding ignored for Negative2 because it is trivially copyable | 
 | // CHECK: -fsanitize-address-field-padding ignored for Negative3 because it is a union | 
 | // CHECK: -fsanitize-address-field-padding ignored for Negative4 because it is trivially copyable | 
 | // CHECK: -fsanitize-address-field-padding ignored for Negative5 because it is packed | 
 | // CHECK: -fsanitize-address-field-padding ignored for SomeNamespace::BlacklistedByName because it is blacklisted | 
 | // CHECK: -fsanitize-address-field-padding ignored for ExternCStruct because it is not C++ | 
 | // | 
 | // FILE_BLACKLIST: -fsanitize-address-field-padding ignored for Positive1 because it is in a blacklisted file | 
 | // FILE_BLACKLIST-NOT: __asan_poison_intra_object_redzone | 
 | // NO_PADDING-NOT: __asan_poison_intra_object_redzone | 
 |  | 
 |  | 
 | class Positive1 { | 
 |  public: | 
 |   Positive1() {} | 
 |   ~Positive1() {} | 
 |   int make_it_non_standard_layout; | 
 |  private: | 
 |   char private1; | 
 |   int private2; | 
 |   short private_array[6]; | 
 |   long long private3; | 
 | }; | 
 |  | 
 | Positive1 positive1; | 
 | // Positive1 with extra paddings | 
 | // CHECK: type { i32, [12 x i8], i8, [15 x i8], i32, [12 x i8], [6 x i16], [12 x i8], i64, [8 x i8] } | 
 |  | 
 | struct VirtualBase { | 
 |   int foo; | 
 | }; | 
 |  | 
 | class ClassWithVirtualBase : public virtual VirtualBase { | 
 |  public: | 
 |   ClassWithVirtualBase() {} | 
 |   ~ClassWithVirtualBase() {} | 
 |   int make_it_non_standard_layout; | 
 |  private: | 
 |   char x[7]; | 
 |   char y[9]; | 
 | }; | 
 |  | 
 | ClassWithVirtualBase class_with_virtual_base; | 
 |  | 
 | class WithFlexibleArray1 { | 
 |  public: | 
 |   WithFlexibleArray1() {} | 
 |   ~WithFlexibleArray1() {} | 
 |   int make_it_non_standard_layout; | 
 |  private: | 
 |   char private1[33]; | 
 |   int flexible[];  // Don't insert padding after this field. | 
 | }; | 
 |  | 
 | WithFlexibleArray1 with_flexible_array1; | 
 | // CHECK: %class.WithFlexibleArray1 = type { i32, [12 x i8], [33 x i8], [15 x i8], [0 x i32] } | 
 |  | 
 | class WithFlexibleArray2 { | 
 |  public: | 
 |   char x[21]; | 
 |   WithFlexibleArray1 flex1;  // Don't insert padding after this field. | 
 | }; | 
 |  | 
 | WithFlexibleArray2 with_flexible_array2; | 
 | // CHECK: %class.WithFlexibleArray2 = type { [21 x i8], [11 x i8], %class.WithFlexibleArray1 } | 
 |  | 
 | class WithFlexibleArray3 { | 
 |  public: | 
 |   char x[13]; | 
 |   WithFlexibleArray2 flex2;  // Don't insert padding after this field. | 
 | }; | 
 |  | 
 | WithFlexibleArray3 with_flexible_array3; | 
 |  | 
 |  | 
 | class Negative1 { | 
 |  public: | 
 |   Negative1() {} | 
 |   int public1, public2; | 
 | }; | 
 | Negative1 negative1; | 
 | // CHECK: type { i32, i32 } | 
 |  | 
 | class Negative2 { | 
 |  public: | 
 |   Negative2() {} | 
 |  private: | 
 |   int private1, private2; | 
 | }; | 
 | Negative2 negative2; | 
 | // CHECK: type { i32, i32 } | 
 |  | 
 | union Negative3 { | 
 |   char m1[8]; | 
 |   long long m2; | 
 | }; | 
 |  | 
 | Negative3 negative3; | 
 | // CHECK: type { i64 } | 
 |  | 
 | class Negative4 { | 
 |  public: | 
 |   Negative4() {} | 
 |   // No DTOR | 
 |   int make_it_non_standard_layout; | 
 |  private: | 
 |   char private1; | 
 |   int private2; | 
 | }; | 
 |  | 
 | Negative4 negative4; | 
 | // CHECK: type { i32, i8, i32 } | 
 |  | 
 | class __attribute__((packed)) Negative5 { | 
 |  public: | 
 |   Negative5() {} | 
 |   ~Negative5() {} | 
 |   int make_it_non_standard_layout; | 
 |  private: | 
 |   char private1; | 
 |   int private2; | 
 | }; | 
 |  | 
 | Negative5 negative5; | 
 | // CHECK: type <{ i32, i8, i32 }> | 
 |  | 
 |  | 
 | namespace SomeNamespace { | 
 | class BlacklistedByName { | 
 |  public: | 
 |   BlacklistedByName() {} | 
 |   ~BlacklistedByName() {} | 
 |   int make_it_non_standard_layout; | 
 |  private: | 
 |   char private1; | 
 |   int private2; | 
 | }; | 
 | }  // SomeNamespace | 
 |  | 
 | SomeNamespace::BlacklistedByName blacklisted_by_name; | 
 |  | 
 | extern "C" { | 
 | class ExternCStruct { | 
 |  public: | 
 |   ExternCStruct() {} | 
 |   ~ExternCStruct() {} | 
 |   int make_it_non_standard_layout; | 
 |  private: | 
 |   char private1; | 
 |   int private2; | 
 | }; | 
 | }  // extern "C" | 
 |  | 
 | ExternCStruct extern_C_struct; | 
 |  | 
 | // CTOR | 
 | // CHECK-LABEL: define {{.*}}Positive1C1Ev | 
 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}12) | 
 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}15) | 
 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}12) | 
 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}12) | 
 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}}8) | 
 | // CHECK-NOT: __asan_poison_intra_object_redzone | 
 | // CHECK: ret void | 
 | // | 
 | // DTOR | 
 | // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}12) | 
 | // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}15) | 
 | // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}12) | 
 | // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}12) | 
 | // CHECK: call void @__asan_unpoison_intra_object_redzone({{.*}}8) | 
 | // CHECK-NOT: __asan_unpoison_intra_object_redzone | 
 | // CHECK: ret void | 
 | // | 
 | // | 
 | // CHECK-LABEL: define linkonce_odr void @_ZN20ClassWithVirtualBaseC1Ev | 
 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 12) | 
 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 9) | 
 | // CHECK: call void @__asan_poison_intra_object_redzone({{.*}} 15) | 
 | // CHECK-NOT: __asan_poison_intra_object_redzone | 
 | // CHECK: ret void | 
 | // | 
 |  | 
 | struct WithVirtualDtor { | 
 |   virtual ~WithVirtualDtor(); | 
 |   int x, y; | 
 | }; | 
 | struct InheritsFrom_WithVirtualDtor: WithVirtualDtor { | 
 |   int a, b; | 
 |   InheritsFrom_WithVirtualDtor() {} | 
 |   ~InheritsFrom_WithVirtualDtor() {} | 
 | }; | 
 |  | 
 | void Create_InheritsFrom_WithVirtualDtor() { | 
 |   InheritsFrom_WithVirtualDtor x; | 
 | } | 
 |  | 
 |  | 
 | // Make sure the dtor of InheritsFrom_WithVirtualDtor remains in the code, | 
 | // i.e. we ignore -mconstructor-aliases when field paddings are added | 
 | // because the paddings in InheritsFrom_WithVirtualDtor needs to be unpoisoned | 
 | // in the dtor. | 
 | // WITH_CTOR_ALIASES-LABEL: define void @_Z35Create_InheritsFrom_WithVirtualDtor | 
 | // WITH_CTOR_ALIASES-NOT: call void @_ZN15WithVirtualDtorD2Ev | 
 | // WITH_CTOR_ALIASES: call void @_ZN28InheritsFrom_WithVirtualDtorD2Ev | 
 | // WITH_CTOR_ALIASES: ret void | 
 |  | 
 | // Make sure we don't emit memcpy for operator= if paddings are inserted. | 
 | struct ClassWithTrivialCopy { | 
 |   ClassWithTrivialCopy(); | 
 |   ~ClassWithTrivialCopy(); | 
 |   void *a; | 
 |  private: | 
 |   void *c; | 
 | }; | 
 |  | 
 | void MakeTrivialCopy(ClassWithTrivialCopy *s1, ClassWithTrivialCopy *s2) { | 
 |   *s1 = *s2; | 
 |   ClassWithTrivialCopy s3(*s2); | 
 | } | 
 |  | 
 | // CHECK-LABEL: define void @_Z15MakeTrivialCopyP20ClassWithTrivialCopyS0_ | 
 | // CHECK-NOT: memcpy | 
 | // CHECK: ret void |