summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-04-05 18:55:37 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-04-05 18:55:37 +0000
commitb6070db0d0849481c6cd6cd9263530cbbb97b140 (patch)
tree5f1643f7d954c6924a90db53f1264e6707133d9d /clang/test
parent367c2aea4ef30691f8843c8858cdab43c8339983 (diff)
downloadbcm5719-llvm-b6070db0d0849481c6cd6cd9263530cbbb97b140.tar.gz
bcm5719-llvm-b6070db0d0849481c6cd6cd9263530cbbb97b140.zip
DR1672, DR1813, DR1881, DR2120: Implement recent fixes to "standard
layout" rules. The new rules say that a standard-layout struct has its first non-static data member and all base classes at offset 0, and consider a class to not be standard-layout if that would result in multiple subobjects of a single type having the same address. We track "is C++11 standard-layout class" separately from "is standard-layout class" so that the ABIs that need this information can still use it. Differential Revision: https://reviews.llvm.org/D45176 llvm-svn: 329332
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/drs/dr14xx.cpp2
-rw-r--r--clang/test/CXX/drs/dr16xx.cpp30
-rw-r--r--clang/test/CXX/drs/dr18xx.cpp37
-rw-r--r--clang/test/CXX/drs/dr21xx.cpp16
-rw-r--r--clang/test/CXX/drs/dr22xx.cpp2
-rw-r--r--clang/test/Layout/watchos-standard-layout.cpp47
-rw-r--r--clang/test/SemaCXX/type-traits.cpp53
7 files changed, 185 insertions, 2 deletions
diff --git a/clang/test/CXX/drs/dr14xx.cpp b/clang/test/CXX/drs/dr14xx.cpp
index 116437b1ab3..eb5ba3db448 100644
--- a/clang/test/CXX/drs/dr14xx.cpp
+++ b/clang/test/CXX/drs/dr14xx.cpp
@@ -7,6 +7,8 @@
// expected-no-diagnostics
#endif
+// dr1425: na abi
+
namespace dr1460 { // dr1460: 3.5
#if __cplusplus >= 201103L
namespace DRExample {
diff --git a/clang/test/CXX/drs/dr16xx.cpp b/clang/test/CXX/drs/dr16xx.cpp
index 08ae92570ce..898672ab807 100644
--- a/clang/test/CXX/drs/dr16xx.cpp
+++ b/clang/test/CXX/drs/dr16xx.cpp
@@ -3,6 +3,11 @@
// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+#if __cplusplus < 201103L
+// expected-error@+1 {{variadic macro}}
+#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
+#endif
+
namespace dr1611 { // dr1611: dup 1658
struct A { A(int); };
struct B : virtual A { virtual void f() = 0; };
@@ -219,3 +224,28 @@ namespace dr1658 { // dr1658: 5
// assignment case is superseded by dr2180
}
+
+namespace dr1672 { // dr1672: 7
+ struct Empty {};
+ struct A : Empty {};
+ struct B { Empty e; };
+ struct C : A { B b; int n; };
+ struct D : A { int n; B b; };
+
+ static_assert(!__is_standard_layout(C), "");
+ static_assert(__is_standard_layout(D), "");
+
+ struct E { B b; int n; };
+ struct F { int n; B b; };
+ union G { B b; int n; };
+ union H { int n; B b; };
+
+ struct X {};
+ template<typename T> struct Y : X, A { T t; };
+
+ static_assert(!__is_standard_layout(Y<E>), "");
+ static_assert(__is_standard_layout(Y<F>), "");
+ static_assert(!__is_standard_layout(Y<G>), "");
+ static_assert(!__is_standard_layout(Y<H>), "");
+ static_assert(!__is_standard_layout(Y<X>), "");
+}
diff --git a/clang/test/CXX/drs/dr18xx.cpp b/clang/test/CXX/drs/dr18xx.cpp
index e4ec199fcae..a0f470ed4a2 100644
--- a/clang/test/CXX/drs/dr18xx.cpp
+++ b/clang/test/CXX/drs/dr18xx.cpp
@@ -4,9 +4,44 @@
// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
#if __cplusplus < 201103L
-// expected-no-diagnostics
+// expected-error@+1 {{variadic macro}}
+#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
#endif
+namespace dr1813 { // dr1813: 7
+ struct B { int i; };
+ struct C : B {};
+ struct D : C {};
+ struct E : D { char : 4; };
+
+ static_assert(__is_standard_layout(B), "");
+ static_assert(__is_standard_layout(C), "");
+ static_assert(__is_standard_layout(D), "");
+ static_assert(!__is_standard_layout(E), "");
+
+ struct Q {};
+ struct S : Q {};
+ struct T : Q {};
+ struct U : S, T {};
+
+ static_assert(__is_standard_layout(Q), "");
+ static_assert(__is_standard_layout(S), "");
+ static_assert(__is_standard_layout(T), "");
+ static_assert(!__is_standard_layout(U), "");
+}
+
+namespace dr1881 { // dr1881: 7
+ struct A { int a : 4; };
+ struct B : A { int b : 3; };
+ static_assert(__is_standard_layout(A), "");
+ static_assert(!__is_standard_layout(B), "");
+
+ struct C { int : 0; };
+ struct D : C { int : 0; };
+ static_assert(__is_standard_layout(C), "");
+ static_assert(!__is_standard_layout(D), "");
+}
+
void dr1891() { // dr1891: 4
#if __cplusplus >= 201103L
int n;
diff --git a/clang/test/CXX/drs/dr21xx.cpp b/clang/test/CXX/drs/dr21xx.cpp
index 78fc0bec40b..2522ff7dbde 100644
--- a/clang/test/CXX/drs/dr21xx.cpp
+++ b/clang/test/CXX/drs/dr21xx.cpp
@@ -3,6 +3,22 @@
// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+#if __cplusplus < 201103L
+// expected-error@+1 {{variadic macro}}
+#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
+#endif
+
+namespace dr2120 { // dr2120: 7
+ struct A {};
+ struct B : A {};
+ struct C { A a; };
+ struct D { C c[5]; };
+ struct E : B { D d; };
+ static_assert(__is_standard_layout(B), "");
+ static_assert(__is_standard_layout(D), "");
+ static_assert(!__is_standard_layout(E), "");
+}
+
namespace dr2180 { // dr2180: yes
class A {
A &operator=(const A &); // expected-note 0-2{{here}}
diff --git a/clang/test/CXX/drs/dr22xx.cpp b/clang/test/CXX/drs/dr22xx.cpp
index 55b3d782077..021707d876b 100644
--- a/clang/test/CXX/drs/dr22xx.cpp
+++ b/clang/test/CXX/drs/dr22xx.cpp
@@ -3,7 +3,7 @@
// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-namespace dr2229 { // dr2229: yes
+namespace dr2229 { // dr2229: 7
struct AnonBitfieldQualifiers {
const unsigned : 1; // expected-error {{anonymous bit-field cannot have qualifiers}}
volatile unsigned : 1; // expected-error {{anonymous bit-field cannot have qualifiers}}
diff --git a/clang/test/Layout/watchos-standard-layout.cpp b/clang/test/Layout/watchos-standard-layout.cpp
new file mode 100644
index 00000000000..bd7bb1a434b
--- /dev/null
+++ b/clang/test/Layout/watchos-standard-layout.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -triple armv7k-apple-darwin-watchos -fdump-record-layouts %s | FileCheck %s
+
+// WatchOS, 64-bit iOS, and WebAssembly use the C++11 definition of POD to
+// determine whether we can reuse the tail padding of a struct (POD is
+// "trivially copyable and standard layout"). The definition of standard
+// layout changed some time around C++17; check that we still use the old
+// ABI rule.
+
+// B is not standard-layout, but it was under C++11's rule, so we pack
+// C::d into its tail padding anyway.
+struct A { int : 0; };
+struct B : A { int n; char c[3]; };
+struct C : B { char d; };
+int c = sizeof(C);
+static_assert(!__is_standard_layout(B));
+
+// CHECK:*** Dumping AST Record Layout
+// CHECK: 0 | struct C
+// CHECK-NEXT: 0 | struct B (base)
+// CHECK-NEXT: 0 | struct A (base) (empty)
+// CHECK-NEXT: 0:- | int
+// CHECK-NEXT: 0 | int n
+// CHECK-NEXT: 4 | char [3] c
+// CHECK-NEXT: 8 | char d
+// CHECK-NEXT: | [sizeof=12, dsize=9, align=4,
+// CHECK-NEXT: | nvsize=9, nvalign=4]
+
+// F is not standard-layout due to the repeated D base class, but it was under
+// C++11's rule, so we pack G::d into its tail padding anyway.
+struct D {};
+struct E : D {};
+struct F : D, E { int n; char c[3]; };
+struct G : F { G(const G&); char d; };
+int g = sizeof(G);
+static_assert(!__is_standard_layout(F));
+
+// CHECK:*** Dumping AST Record Layout
+// CHECK: 0 | struct G
+// CHECK-NEXT: 0 | struct F (base)
+// CHECK-NEXT: 0 | struct D (base) (empty)
+// CHECK-NEXT: 1 | struct E (base) (empty)
+// CHECK-NEXT: 1 | struct D (base) (empty)
+// CHECK-NEXT: 0 | int n
+// CHECK-NEXT: 4 | char [3] c
+// CHECK-NEXT: 8 | char d
+// CHECK-NEXT: | [sizeof=12, dsize=9, align=4,
+// CHECK-NEXT: | nvsize=9, nvalign=4]
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index ca96503e26b..3370468351e 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -1353,6 +1353,59 @@ void is_standard_layout()
int t43[F(__is_standard_layout(AnIncompleteType[1]))]; // expected-error {{incomplete type}}
int t44[F(__is_standard_layout(void))];
int t45[F(__is_standard_layout(const volatile void))];
+
+ struct HasAnonEmptyBitfield { int : 0; };
+ struct HasAnonBitfield { int : 4; };
+ struct DerivesFromBitfield : HasAnonBitfield {};
+ struct DerivesFromBitfieldWithBitfield : HasAnonBitfield { int : 5; };
+ struct DerivesFromBitfieldTwice : DerivesFromBitfield, HasAnonEmptyBitfield {};
+
+ int t50[T(__is_standard_layout(HasAnonEmptyBitfield))];
+ int t51[T(__is_standard_layout(HasAnonBitfield))];
+ int t52[T(__is_standard_layout(DerivesFromBitfield))];
+ int t53[F(__is_standard_layout(DerivesFromBitfieldWithBitfield))];
+ int t54[F(__is_standard_layout(DerivesFromBitfieldTwice))];
+
+ struct Empty {};
+ struct HasEmptyBase : Empty {};
+ struct HoldsEmptyBase { Empty e; };
+ struct HasRepeatedEmptyBase : Empty, HasEmptyBase {}; // expected-warning {{inaccessible}}
+ struct HasEmptyBaseAsMember : Empty { Empty e; };
+ struct HasEmptyBaseAsSubobjectOfMember1 : Empty { HoldsEmptyBase e; };
+ struct HasEmptyBaseAsSubobjectOfMember2 : Empty { HasEmptyBase e; };
+ struct HasEmptyBaseAsSubobjectOfMember3 : Empty { HoldsEmptyBase e[2]; };
+ struct HasEmptyIndirectBaseAsMember : HasEmptyBase { Empty e; };
+ struct HasEmptyIndirectBaseAsSecondMember : HasEmptyBase { int n; Empty e; };
+ struct HasEmptyIndirectBaseAfterBitfield : HasEmptyBase { int : 4; Empty e; };
+
+ int t60[T(__is_standard_layout(Empty))];
+ int t61[T(__is_standard_layout(HasEmptyBase))];
+ int t62[F(__is_standard_layout(HasRepeatedEmptyBase))];
+ int t63[F(__is_standard_layout(HasEmptyBaseAsMember))];
+ int t64[F(__is_standard_layout(HasEmptyBaseAsSubobjectOfMember1))];
+ int t65[T(__is_standard_layout(HasEmptyBaseAsSubobjectOfMember2))]; // FIXME: standard bug?
+ int t66[F(__is_standard_layout(HasEmptyBaseAsSubobjectOfMember3))];
+ int t67[F(__is_standard_layout(HasEmptyIndirectBaseAsMember))];
+ int t68[T(__is_standard_layout(HasEmptyIndirectBaseAsSecondMember))];
+ int t69[F(__is_standard_layout(HasEmptyIndirectBaseAfterBitfield))]; // FIXME: standard bug?
+
+ struct StructWithEmptyFields {
+ int n;
+ HoldsEmptyBase e[3];
+ };
+ union UnionWithEmptyFields {
+ int n;
+ HoldsEmptyBase e[3];
+ };
+ struct HasEmptyIndirectBaseAsSecondStructMember : HasEmptyBase {
+ StructWithEmptyFields u;
+ };
+ struct HasEmptyIndirectBaseAsSecondUnionMember : HasEmptyBase {
+ UnionWithEmptyFields u;
+ };
+
+ int t70[T(__is_standard_layout(HasEmptyIndirectBaseAsSecondStructMember))];
+ int t71[F(__is_standard_layout(HasEmptyIndirectBaseAsSecondUnionMember))];
}
void is_signed()
OpenPOWER on IntegriCloud