diff options
author | Erich Keane <erich.keane@intel.com> | 2017-11-30 16:37:02 +0000 |
---|---|---|
committer | Erich Keane <erich.keane@intel.com> | 2017-11-30 16:37:02 +0000 |
commit | c48afae870f98e8b0a4e519344d47e10427ab7d1 (patch) | |
tree | 463aaec01a8e3fb23690cbd1c26b331f42583c87 /test/SemaCXX | |
parent | 96c9689f478d292390b76efcea35d87cbad3f44d (diff) |
Fix __has_unique_object_representations implementation
As rsmith pointed out, the original implementation of this intrinsic
missed a number of important situations. This patch fixe a bunch of
shortcomings and implementation details to make it work correctly.
Differential Revision: https://reviews.llvm.org/D39347
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@319446 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaCXX')
-rw-r--r-- | test/SemaCXX/has_unique_object_reps_member_ptr.cpp | 32 | ||||
-rw-r--r-- | test/SemaCXX/type-traits.cpp | 86 |
2 files changed, 113 insertions, 5 deletions
diff --git a/test/SemaCXX/has_unique_object_reps_member_ptr.cpp b/test/SemaCXX/has_unique_object_reps_member_ptr.cpp new file mode 100644 index 0000000000..b8e27f82ff --- /dev/null +++ b/test/SemaCXX/has_unique_object_reps_member_ptr.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple x86_64-linux-pc -DIS64 -fsyntax-only -verify -std=c++17 %s +// RUN: %clang_cc1 -triple x86_64-windows-pc -DIS64 -fsyntax-only -verify -std=c++17 %s +// RUN: %clang_cc1 -triple i386-linux-pc -fsyntax-only -verify -std=c++17 %s +// RUN: %clang_cc1 -triple i386-windows-pc -DW32 -fsyntax-only -verify -std=c++17 %s +// expected-no-diagnostics + +struct Base {}; +struct A : virtual Base { + virtual void n() {} +}; + +auto p = &A::n; +static_assert(__has_unique_object_representations(decltype(p))); + +struct B { + decltype(p) x; + int b; +#ifdef IS64 + // required on 64 bit to fill out the tail padding. + int c; +#endif +}; +static_assert(__has_unique_object_representations(B)); + +struct C { // has padding on Win32, but nothing else. + decltype(p) x; +}; +#ifdef W32 +static_assert(!__has_unique_object_representations(C)); +#else +static_assert(__has_unique_object_representations(C)); +#endif diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index d6a3574f93..d4d1968218 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -2447,7 +2447,7 @@ struct Padding { int b; }; -static_assert(!has_unique_object_representations<Padding>::value, "but not with padding"); +//static_assert(!has_unique_object_representations<Padding>::value, "but not with padding"); struct InheritsFromPadding : Padding { int c; @@ -2518,12 +2518,11 @@ enum class LLEnumClass : long long { xLongExample, static_assert(has_unique_object_representations<ExampleEnumClass>::value, "Enums are integrals, so unique!"); static_assert(has_unique_object_representations<LLEnumClass>::value, "Enums are integrals, so unique!"); -// because reference types aren't object types +// because references aren't trivially copyable. static_assert(!has_unique_object_representations<int &>::value, "No references!"); static_assert(!has_unique_object_representations<const int &>::value, "No references!"); static_assert(!has_unique_object_representations<volatile int &>::value, "No references!"); static_assert(!has_unique_object_representations<const volatile int &>::value, "No references!"); - static_assert(!has_unique_object_representations<Empty>::value, "No empty types!"); class Compressed : Empty { @@ -2556,6 +2555,16 @@ static_assert(!has_unique_object_representations<double[42]>::value, "So no arra static_assert(!has_unique_object_representations<double[]>::value, "So no array of doubles!"); static_assert(!has_unique_object_representations<double[][42]>::value, "So no array of doubles!"); +struct __attribute__((aligned(16))) WeirdAlignment { + int i; +}; +union __attribute__((aligned(16))) WeirdAlignmentUnion { + int i; +}; +static_assert(!has_unique_object_representations<WeirdAlignment>::value, "Alignment causes padding"); +static_assert(!has_unique_object_representations<WeirdAlignmentUnion>::value, "Alignment causes padding"); +static_assert(!has_unique_object_representations<WeirdAlignment[42]>::value, "Also no arrays that have padding"); + static_assert(!has_unique_object_representations<int(int)>::value, "Functions are not unique"); static_assert(!has_unique_object_representations<int(int) const>::value, "Functions are not unique"); static_assert(!has_unique_object_representations<int(int) volatile>::value, "Functions are not unique"); @@ -2582,6 +2591,73 @@ static_assert(!has_unique_object_representations<int(int, ...) const &&>::value, static_assert(!has_unique_object_representations<int(int, ...) volatile &&>::value, "Functions are not unique"); static_assert(!has_unique_object_representations<int(int, ...) const volatile &&>::value, "Functions are not unique"); -static auto lambda = []() {}; -static_assert(!has_unique_object_representations<decltype(lambda)>::value, "Lambdas are not unique"); +void foo(){ + static auto lambda = []() {}; + static_assert(!has_unique_object_representations<decltype(lambda)>::value, "Lambdas follow struct rules"); + int i; + static auto lambda2 = [i]() {}; + static_assert(has_unique_object_representations<decltype(lambda2)>::value, "Lambdas follow struct rules"); +} + +struct PaddedBitfield { + char c : 6; + char d : 1; +}; + +struct UnPaddedBitfield { + char c : 6; + char d : 2; +}; + +struct AlignedPaddedBitfield { + char c : 6; + __attribute__((aligned(1))) + char d : 2; +}; + +static_assert(!has_unique_object_representations<PaddedBitfield>::value, "Bitfield padding"); +static_assert(has_unique_object_representations<UnPaddedBitfield>::value, "Bitfield padding"); +static_assert(!has_unique_object_representations<AlignedPaddedBitfield>::value, "Bitfield padding"); + +struct BoolBitfield { + bool b : 8; +}; + +static_assert(has_unique_object_representations<BoolBitfield>::value, "Bitfield bool"); + +struct BoolBitfield2 { + bool b : 16; +}; + +static_assert(!has_unique_object_representations<BoolBitfield2>::value, "Bitfield bool"); + +struct GreaterSizeBitfield { + //expected-warning@+1 {{width of bit-field 'n'}} + int n : 1024; +}; + +static_assert(sizeof(GreaterSizeBitfield) == 128, "Bitfield Size"); +static_assert(!has_unique_object_representations<GreaterSizeBitfield>::value, "Bitfield padding"); + +struct StructWithRef { + int &I; +}; + +static_assert(has_unique_object_representations<StructWithRef>::value, "References are still unique"); + +struct NotUniqueBecauseTailPadding { + int &r; + char a; +}; +struct CanBeUniqueIfNoPadding : NotUniqueBecauseTailPadding { + char b[7]; +}; + +static_assert(!has_unique_object_representations<NotUniqueBecauseTailPadding>::value, + "non trivial"); +// Can be unique on Itanium, since the is child class' data is 'folded' into the +// parent's tail padding. +static_assert(sizeof(CanBeUniqueIfNoPadding) != 16 || + has_unique_object_representations<CanBeUniqueIfNoPadding>::value, + "inherit from std layout"); |