diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-04-29 04:55:46 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-04-29 04:55:46 +0000 |
commit | 3d0b7546132a9a667122e457b3baec4cd03947e0 (patch) | |
tree | 26fdd9041deb9ccd4c2fbc8faadfa3e424b510ea /test/CodeGenCXX/alignment.cpp | |
parent | fc26ba15dd3d6c4e30e868b08110d9d87a21107a (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.cpp | 33 |
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 |