summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/pod-member-memcpys.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX/pod-member-memcpys.cpp')
-rw-r--r--test/CodeGenCXX/pod-member-memcpys.cpp256
1 files changed, 256 insertions, 0 deletions
diff --git a/test/CodeGenCXX/pod-member-memcpys.cpp b/test/CodeGenCXX/pod-member-memcpys.cpp
new file mode 100644
index 0000000..534d5d1
--- /dev/null
+++ b/test/CodeGenCXX/pod-member-memcpys.cpp
@@ -0,0 +1,256 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++03 -fexceptions -fcxx-exceptions -O1 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -std=c++03 -O0 -o - %s | FileCheck --check-prefix=CHECK-2 %s
+
+struct POD {
+ int w, x, y, z;
+};
+
+struct PODLike {
+ int w, x, y, z;
+ PODLike();
+ ~PODLike();
+};
+
+struct NonPOD {
+ NonPOD();
+ NonPOD(const NonPOD&);
+ NonPOD& operator=(const NonPOD&);
+};
+
+struct Basic {
+ int a, b, c, d;
+ NonPOD np;
+ int w, x, y, z;
+};
+
+struct PODMember {
+ int a, b, c, d;
+ POD p;
+ NonPOD np;
+ int w, x, y, z;
+};
+
+struct PODLikeMember {
+ int a, b, c, d;
+ PODLike pl;
+ NonPOD np;
+ int w, x, y, z;
+};
+
+struct ArrayMember {
+ int a, b, c, d;
+ int e[12];
+ NonPOD np;
+ int f[12];
+ int w, x, y, z;
+};
+
+struct VolatileMember {
+ int a, b, c, d;
+ volatile int v;
+ NonPOD np;
+ int w, x, y, z;
+};
+
+struct BitfieldMember {
+ int a, b, c, d;
+ NonPOD np;
+ int w : 6;
+ int x : 6;
+ int y : 6;
+ int z : 6;
+};
+
+struct BitfieldMember2 {
+ unsigned a : 1;
+ unsigned b, c, d;
+ NonPOD np;
+};
+
+struct InnerClassMember {
+ struct {
+ int a, b, c, d;
+ } a;
+ int b, c, d, e;
+ NonPOD np;
+ int w, x, y, z;
+};
+
+struct ReferenceMember {
+ ReferenceMember(int &a, int &b, int &c, int &d)
+ : a(a), b(b), c(c), d(d) {}
+ int &a;
+ int &b;
+ NonPOD np;
+ int &c;
+ 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.
+
+#define CALL_AO(T) void callAO##T(T& a, const T& b) { a = b; }
+
+CALL_AO(Basic)
+CALL_AO(PODMember)
+CALL_AO(PODLikeMember)
+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*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: ret %struct.Basic* %this
+
+// PODMember copy-assignment:
+// CHECK: define linkonce_odr %struct.PODMember* @_ZN9PODMemberaSERKS_(%struct.PODMember* %this, %struct.PODMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
+// CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: ret %struct.PODMember* %this
+
+// PODLikeMember copy-assignment:
+// CHECK: define linkonce_odr %struct.PODLikeMember* @_ZN13PODLikeMemberaSERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
+// CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: ret %struct.PODLikeMember* %this
+
+// ArrayMember copy-assignment:
+// CHECK: define linkonce_odr %struct.ArrayMember* @_ZN11ArrayMemberaSERKS_(%struct.ArrayMember* %this, %struct.ArrayMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
+// CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
+// CHECK: ret %struct.ArrayMember* %this
+
+// VolatileMember copy-assignment:
+// CHECK: define linkonce_odr %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: load volatile i32* {{.*}}, align 4
+// CHECK: store volatile i32 {{.*}}, align 4
+// CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: ret %struct.VolatileMember* %this
+
+// BitfieldMember copy-assignment:
+// CHECK: define linkonce_odr %struct.BitfieldMember* @_ZN14BitfieldMemberaSERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
+// CHECK: ret %struct.BitfieldMember* %this
+
+// InnerClass copy-assignment:
+// CHECK: define linkonce_odr %struct.InnerClassMember* @_ZN16InnerClassMemberaSERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
+// CHECK: tail call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// 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
+// copy-constructor calls are encountered. Add functions that call the copy
+// constructors of the classes above in reverse order here.
+
+#define CALL_CC(T) T callCC##T(const T& b) { return b; }
+
+CALL_CC(PackedMembers)
+CALL_CC(BitfieldMember2)
+CALL_CC(ReferenceMember)
+CALL_CC(InnerClassMember)
+CALL_CC(BitfieldMember)
+CALL_CC(VolatileMember)
+CALL_CC(ArrayMember)
+CALL_CC(PODLikeMember)
+CALL_CC(PODMember)
+CALL_CC(Basic)
+
+// Basic copy-constructor:
+// CHECK: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: tail call void @_ZN6NonPODC1ERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: ret void
+
+// PODMember copy-constructor:
+// CHECK: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
+// CHECK: tail call void @_ZN6NonPODC1ERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: ret void
+
+// PODLikeMember copy-constructor:
+// CHECK: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
+// CHECK: invoke void @_ZN6NonPODC1ERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: ret void
+// CHECK: landingpad
+// CHECK: invoke void @_ZN7PODLikeD1Ev
+
+// ArrayMember copy-constructor:
+// CHECK: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
+// CHECK: tail call void @_ZN6NonPODC1ERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
+// CHECK: ret void
+
+// VolatileMember copy-constructor:
+// CHECK: define linkonce_odr void @_ZN14VolatileMemberC2ERKS_(%struct.VolatileMember* %this, %struct.VolatileMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: load volatile i32* {{.*}}, align 4
+// CHECK: store volatile i32 {{.*}}, align 4
+// CHECK: tail call void @_ZN6NonPODC1ERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: ret void
+
+// BitfieldMember copy-constructor:
+// CHECK: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: tail call void @_ZN6NonPODC1ERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
+// CHECK: ret void
+
+// InnerClass copy-constructor:
+// CHECK: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
+// CHECK: tail call void @_ZN6NonPODC1ERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
+// CHECK: ret void
+
+// ReferenceMember copy-constructor:
+// CHECK: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember*)
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
+// CHECK: tail call void @_ZN6NonPODC1ERKS_
+// CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
+// CHECK: ret void
+
+// BitfieldMember2 copy-constructor:
+// CHECK-2: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2*)
+// 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
OpenPOWER on IntegriCloud