summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/alignment.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-04-29 04:55:46 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-04-29 04:55:46 +0000
commit3d0b7546132a9a667122e457b3baec4cd03947e0 (patch)
tree26fdd9041deb9ccd4c2fbc8faadfa3e424b510ea /test/CodeGenCXX/alignment.cpp
parentfc26ba15dd3d6c4e30e868b08110d9d87a21107a (diff)
PR37275 packed attribute should not apply to base classes
Clang incorrectly applied the packed attribute to base classes. Per GCC's documentation and as can be observed from its behavior, packed only applies to members, not base classes. This change is conditioned behind -fclang-abi-compat so that an ABI break can be avoided by users if desired. Differential Revision: https://reviews.llvm.org/D46218 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331136 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/alignment.cpp')
-rw-r--r--test/CodeGenCXX/alignment.cpp33
1 files changed, 22 insertions, 11 deletions
diff --git a/test/CodeGenCXX/alignment.cpp b/test/CodeGenCXX/alignment.cpp
index 49cb34402c..2549afda88 100644
--- a/test/CodeGenCXX/alignment.cpp
+++ b/test/CodeGenCXX/alignment.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOCOMPAT
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 -fclang-abi-compat=6.0 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V6COMPAT
extern int int_source();
extern void int_sink(int x);
@@ -54,11 +55,13 @@ namespace test0 {
// CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B]]*
// CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
// CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i8
- // CHECK: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-V6COMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
// CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 3
// CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -4
// CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]
- // CHECK: store i8 [[T2]], i8* [[FIELD_P]], align 2
+ // CHECK-V6COMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 4
c.onebit = int_source();
// CHECK: [[C_P:%.*]] = load [[C]]*, [[C]]**
@@ -66,7 +69,8 @@ namespace test0 {
// CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
// CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B]]*
// CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
- // CHECK: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-V6COMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
// CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 6
// CHECK: [[T1:%.*]] = ashr i8 [[T0]], 6
// CHECK: [[T2:%.*]] = sext i8 [[T1]] to i32
@@ -83,11 +87,13 @@ namespace test0 {
// CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B]]*
// CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
// CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i8
- // CHECK: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-V6COMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
// CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 3
// CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -4
// CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]
- // CHECK: store i8 [[T2]], i8* [[FIELD_P]], align 2
+ // CHECK-V6COMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 4
c->onebit = int_source();
// CHECK: [[C_P:%.*]] = load [[C:%.*]]*, [[C]]**
@@ -95,7 +101,8 @@ namespace test0 {
// CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
// CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B:%.*]]*
// CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
- // CHECK: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-V6COMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
// CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 6
// CHECK: [[T1:%.*]] = ashr i8 [[T0]], 6
// CHECK: [[T2:%.*]] = sext i8 [[T1]] to i32
@@ -107,7 +114,8 @@ namespace test0 {
// in an alignment-2 variable.
// CHECK-LABEL: @_ZN5test01dEv
void d() {
- // CHECK: [[C_P:%.*]] = alloca [[C:%.*]], align 2
+ // CHECK-V6COMPAT: [[C_P:%.*]] = alloca [[C:%.*]], align 2
+ // CHECK-NOCOMPAT: [[C_P:%.*]] = alloca [[C:%.*]], align 4
C c;
// CHECK: [[CALL:%.*]] = call i32 @_Z10int_sourcev()
@@ -116,18 +124,21 @@ namespace test0 {
// CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B]]*
// CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
// CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i8
- // CHECK: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-V6COMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[OLD_VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
// CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 3
// CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -4
// CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]
- // CHECK: store i8 [[T2]], i8* [[FIELD_P]], align 2
+ // CHECK-V6COMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: store i8 [[T2]], i8* [[FIELD_P]], align 4
c.onebit = int_source();
// CHECK: [[T0:%.*]] = bitcast [[C]]* [[C_P]] to i8*
// CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 8
// CHECK: [[B_P:%.*]] = bitcast i8* [[T1]] to [[B:%.*]]*
// CHECK: [[FIELD_P:%.*]] = bitcast [[B]]* [[B_P]] to i8*
- // CHECK: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-V6COMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 2
+ // CHECK-NOCOMPAT: [[VALUE:%.*]] = load i8, i8* [[FIELD_P]], align 4
// CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 6
// CHECK: [[T1:%.*]] = ashr i8 [[T0]], 6
// CHECK: [[T2:%.*]] = sext i8 [[T1]] to i32