diff options
author | Lang Hames <lhames@gmail.com> | 2013-03-05 20:27:24 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2013-03-05 20:27:24 +0000 |
commit | 224ae88bc3f3c0ad43a50da048a2f789898a18cf (patch) | |
tree | 4ad34a59cae2828e593260e17c5d2fb4f3b01fb2 /clang | |
parent | 37f2ab4824ec3309ee3b578efc2839cdf4ce2a24 (diff) | |
download | bcm5719-llvm-224ae88bc3f3c0ad43a50da048a2f789898a18cf.tar.gz bcm5719-llvm-224ae88bc3f3c0ad43a50da048a2f789898a18cf.zip |
Use ASTContext::getDeclAlign(<Field Decl>) to get the alignment of the first
field to be memcpy'd, rather instead of ASTContext::getTypeAlign(<Field Type>).
For packed structs the alignment of a field may be less than the alignment of
the field's type.
<rdar://problem/13338585>
llvm-svn: 176512
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 4 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/pod-member-memcpys.cpp | 20 |
2 files changed, 21 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index ac2dada0834..4319e43b91b 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -794,9 +794,7 @@ namespace { const CGBitFieldInfo &BFInfo = RL.getBitFieldInfo(FirstField); Alignment = CharUnits::fromQuantity(BFInfo.StorageAlignment); } else { - unsigned AlignBits = - CGF.getContext().getTypeAlign(FirstField->getType()); - Alignment = CGF.getContext().toCharUnitsFromBits(AlignBits); + Alignment = CGF.getContext().getDeclAlign(FirstField); } assert((CGF.getContext().toCharUnitsFromBits(FirstFieldOffset) % diff --git a/clang/test/CodeGenCXX/pod-member-memcpys.cpp b/clang/test/CodeGenCXX/pod-member-memcpys.cpp index 1e76c08899a..534d5d19e99 100644 --- a/clang/test/CodeGenCXX/pod-member-memcpys.cpp +++ b/clang/test/CodeGenCXX/pod-member-memcpys.cpp @@ -86,6 +86,12 @@ struct ReferenceMember { int &d; }; +struct __attribute__((packed)) PackedMembers { + char c; + NonPOD np; + int w, x, y, z; +}; + // COPY-ASSIGNMENT OPERATORS: // Assignment operators are output in the order they're encountered. @@ -99,6 +105,7 @@ CALL_AO(ArrayMember) CALL_AO(VolatileMember) CALL_AO(BitfieldMember) CALL_AO(InnerClassMember) +CALL_AO(PackedMembers) // Basic copy-assignment: // CHECK: define linkonce_odr %struct.Basic* @_ZN5BasicaSERKS_(%struct.Basic* %this, %struct.Basic*) @@ -151,6 +158,12 @@ CALL_AO(InnerClassMember) // CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) // CHECK: ret %struct.InnerClassMember* %this +// PackedMembers copy-assignment: +// CHECK: define linkonce_odr %struct.PackedMembers* @_ZN13PackedMembersaSERKS_(%struct.PackedMembers* %this, %struct.PackedMembers*) +// CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_ +// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}}) +// CHECK: ret %struct.PackedMembers* %this + // COPY-CONSTRUCTORS: // Clang outputs copy-constructors in the reverse of the order that @@ -159,6 +172,7 @@ CALL_AO(InnerClassMember) #define CALL_CC(T) T callCC##T(const T& b) { return b; } +CALL_CC(PackedMembers) CALL_CC(BitfieldMember2) CALL_CC(ReferenceMember) CALL_CC(InnerClassMember) @@ -234,3 +248,9 @@ CALL_CC(Basic) // CHECK-2: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4, i1 false) // CHECK-2: call void @_ZN6NonPODC1ERKS_ // CHECK-2: ret void + +// PackedMembers copy-assignment: +// CHECK: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers*) +// CHECK: tail call void @_ZN6NonPODC1ERKS_ +// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}}) +// CHECK: ret void |